@woosh/meep-engine 2.43.45 → 2.43.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/editor/process/symbolic/makeSolidArrowGeometry.js +391 -0
- package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +138 -7
- package/engine/graphics/ecs/mesh-v2/render/adapters/InstancedRendererAdapter.js +2 -5
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +49 -5
- package/package.json +1 -1
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { StreamGeometryBuilder } from "../../../engine/graphics/ecs/path/tube/build/StreamGeometryBuilder.js";
|
|
2
|
+
import { make_ring_faces } from "../../../engine/graphics/ecs/path/tube/build/make_ring_faces.js";
|
|
3
|
+
import { BufferGeometry } from "three/src/core/BufferGeometry.js";
|
|
4
|
+
import { Float32BufferAttribute } from "three/src/core/BufferAttribute.js";
|
|
5
|
+
import { Vector2, Vector3 } from "three";
|
|
6
|
+
|
|
7
|
+
// Modified from https://github.com/mrdoob/three.js/blob/master/src/geometries/CylinderBufferGeometry.js
|
|
8
|
+
class ArrowBufferGeometry extends BufferGeometry {
|
|
9
|
+
|
|
10
|
+
constructor( {radiusTop = 1/7, radiusBottom = 1/20, height = 1, heightTop = 0.6, radialSegments = 8, heightSegments = 1, openEnded = false, heightIncludesHead = true} = {} ) {
|
|
11
|
+
|
|
12
|
+
super();
|
|
13
|
+
this.type = 'ArrowBufferGeometry';
|
|
14
|
+
|
|
15
|
+
this.parameters = {
|
|
16
|
+
radiusTop: radiusTop,
|
|
17
|
+
radiusBottom: radiusBottom,
|
|
18
|
+
height: height,
|
|
19
|
+
heightTop: heightTop,
|
|
20
|
+
radialSegments: radialSegments,
|
|
21
|
+
heightSegments: heightSegments,
|
|
22
|
+
openEnded: openEnded,
|
|
23
|
+
heightIncludesHead: heightIncludesHead,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const scope = this;
|
|
27
|
+
const thetaStart = 0, thetaLength = 2 * Math.PI;
|
|
28
|
+
|
|
29
|
+
radialSegments = Math.floor( radialSegments );
|
|
30
|
+
heightSegments = Math.floor( heightSegments );
|
|
31
|
+
|
|
32
|
+
// buffers
|
|
33
|
+
|
|
34
|
+
const indices = [];
|
|
35
|
+
const vertices = [];
|
|
36
|
+
const normals = [];
|
|
37
|
+
const uvs = [];
|
|
38
|
+
|
|
39
|
+
// helper variables
|
|
40
|
+
|
|
41
|
+
let index = 0;
|
|
42
|
+
const indexArray = [];
|
|
43
|
+
const halfHeight = height / 2;
|
|
44
|
+
const tubeHeight = heightIncludesHead ? height - heightTop : height;
|
|
45
|
+
let groupStart = 0;
|
|
46
|
+
|
|
47
|
+
// generate geometry
|
|
48
|
+
|
|
49
|
+
generateTorso();
|
|
50
|
+
generateCap( true );
|
|
51
|
+
generateCap( false, true );
|
|
52
|
+
|
|
53
|
+
if ( openEnded === false ) {
|
|
54
|
+
|
|
55
|
+
if ( radiusBottom > 0 ) generateCap( false );
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// build geometry
|
|
60
|
+
|
|
61
|
+
this.setIndex( indices );
|
|
62
|
+
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
63
|
+
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
|
64
|
+
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
65
|
+
|
|
66
|
+
function generateTorso() {
|
|
67
|
+
|
|
68
|
+
const normal = new Vector3();
|
|
69
|
+
const vertex = new Vector3();
|
|
70
|
+
|
|
71
|
+
let groupCount = 0;
|
|
72
|
+
|
|
73
|
+
// this will be used to calculate the normal
|
|
74
|
+
const slope = 0;
|
|
75
|
+
|
|
76
|
+
// generate vertices, normals and uvs
|
|
77
|
+
|
|
78
|
+
for ( let y = 0; y <= heightSegments; y ++ ) {
|
|
79
|
+
|
|
80
|
+
const indexRow = [];
|
|
81
|
+
|
|
82
|
+
const v = y / heightSegments;
|
|
83
|
+
|
|
84
|
+
// calculate the radius of the current row
|
|
85
|
+
|
|
86
|
+
const radius = radiusBottom;
|
|
87
|
+
|
|
88
|
+
for ( let x = 0; x <= radialSegments; x ++ ) {
|
|
89
|
+
|
|
90
|
+
const u = x / radialSegments;
|
|
91
|
+
|
|
92
|
+
const theta = u * Math.PI * 2;
|
|
93
|
+
|
|
94
|
+
const sinTheta = Math.sin( theta );
|
|
95
|
+
const cosTheta = Math.cos( theta );
|
|
96
|
+
|
|
97
|
+
// vertex
|
|
98
|
+
|
|
99
|
+
vertex.x = radius * cosTheta;
|
|
100
|
+
vertex.y = radius * sinTheta;
|
|
101
|
+
vertex.z = v * tubeHeight;
|
|
102
|
+
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
103
|
+
|
|
104
|
+
// normal
|
|
105
|
+
|
|
106
|
+
normal.set( cosTheta, sinTheta, 0 ).normalize();
|
|
107
|
+
normals.push( normal.x, normal.y, normal.z );
|
|
108
|
+
|
|
109
|
+
// uv
|
|
110
|
+
|
|
111
|
+
uvs.push( u, 1 - v );
|
|
112
|
+
|
|
113
|
+
// save index of vertex in respective row
|
|
114
|
+
|
|
115
|
+
indexRow.push( index ++ );
|
|
116
|
+
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// now save vertices of the row in our index array
|
|
120
|
+
|
|
121
|
+
indexArray.push( indexRow );
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// generate indices
|
|
126
|
+
|
|
127
|
+
for ( let x = 0; x < radialSegments; x ++ ) {
|
|
128
|
+
|
|
129
|
+
for ( let y = 0; y < heightSegments; y ++ ) {
|
|
130
|
+
|
|
131
|
+
// we use the index array to access the correct indices
|
|
132
|
+
|
|
133
|
+
const a = indexArray[ y ][ x ];
|
|
134
|
+
const b = indexArray[ y + 1 ][ x ];
|
|
135
|
+
const c = indexArray[ y + 1 ][ x + 1 ];
|
|
136
|
+
const d = indexArray[ y ][ x + 1 ];
|
|
137
|
+
|
|
138
|
+
// faces
|
|
139
|
+
|
|
140
|
+
indices.push( b, a, d );
|
|
141
|
+
indices.push( c, b, d );
|
|
142
|
+
|
|
143
|
+
// update group counter
|
|
144
|
+
|
|
145
|
+
groupCount += 6;
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// add a group to the geometry. this will ensure multi material support
|
|
152
|
+
|
|
153
|
+
scope.addGroup( groupStart, groupCount, 0 );
|
|
154
|
+
|
|
155
|
+
// calculate new start value for groups
|
|
156
|
+
|
|
157
|
+
groupStart += groupCount;
|
|
158
|
+
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function generateCap( top, headBase = false ) {
|
|
162
|
+
|
|
163
|
+
// save the index of the first center vertex
|
|
164
|
+
const centerIndexStart = index;
|
|
165
|
+
|
|
166
|
+
const uv = new Vector2();
|
|
167
|
+
const vertex = new Vector3();
|
|
168
|
+
|
|
169
|
+
let groupCount = 0;
|
|
170
|
+
|
|
171
|
+
const radius = ( top || headBase ) ? radiusTop : radiusBottom;
|
|
172
|
+
const sign = ( top ) ? 1 : -1;
|
|
173
|
+
|
|
174
|
+
// first we generate the center vertex data of the cap.
|
|
175
|
+
// because the geometry needs one set of uvs per face,
|
|
176
|
+
// we must generate a center vertex per face/segment
|
|
177
|
+
|
|
178
|
+
for ( let x = 1; x <= radialSegments; x ++ ) {
|
|
179
|
+
|
|
180
|
+
// vertex
|
|
181
|
+
|
|
182
|
+
vertices.push( 0, 0, top ? tubeHeight + heightTop : (headBase ? tubeHeight : 0) );
|
|
183
|
+
|
|
184
|
+
// normal
|
|
185
|
+
|
|
186
|
+
if (top) {
|
|
187
|
+
const theta = (x - 1/2) / radialSegments * Math.PI * 2;
|
|
188
|
+
const sinTheta = Math.sin(theta), cosTheta = Math.cos(theta);
|
|
189
|
+
const normal = new Vector3( cosTheta, sinTheta, radiusTop / heightTop );
|
|
190
|
+
normal.normalize();
|
|
191
|
+
normals.push( normal.x, normal.y, normal.z);
|
|
192
|
+
} else {
|
|
193
|
+
normals.push( 0, 0, sign );
|
|
194
|
+
}
|
|
195
|
+
// uv
|
|
196
|
+
|
|
197
|
+
uvs.push( 0.5, 0.5 );
|
|
198
|
+
|
|
199
|
+
// increase index
|
|
200
|
+
|
|
201
|
+
index ++;
|
|
202
|
+
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// save the index of the last center vertex
|
|
206
|
+
const centerIndexEnd = index;
|
|
207
|
+
|
|
208
|
+
// now we generate the surrounding vertices, normals and uvs
|
|
209
|
+
|
|
210
|
+
for ( let x = 0; x <= radialSegments; x ++ ) {
|
|
211
|
+
|
|
212
|
+
const u = x / radialSegments;
|
|
213
|
+
const theta = u * thetaLength + thetaStart;
|
|
214
|
+
|
|
215
|
+
const cosTheta = Math.cos( theta );
|
|
216
|
+
const sinTheta = Math.sin( theta );
|
|
217
|
+
|
|
218
|
+
// vertex
|
|
219
|
+
|
|
220
|
+
vertex.x = radius * cosTheta;
|
|
221
|
+
vertex.y = radius * sinTheta;
|
|
222
|
+
vertex.z = top || headBase ? tubeHeight : 0;
|
|
223
|
+
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
224
|
+
|
|
225
|
+
// normal
|
|
226
|
+
|
|
227
|
+
if (top) {
|
|
228
|
+
const normal = new Vector3(cosTheta, sinTheta, radiusTop / heightTop );
|
|
229
|
+
normal.normalize();
|
|
230
|
+
normals.push( normal.x, normal.y, normal.z);
|
|
231
|
+
} else {
|
|
232
|
+
normals.push( 0, 0, sign );
|
|
233
|
+
}
|
|
234
|
+
// uv
|
|
235
|
+
|
|
236
|
+
uv.x = ( cosTheta * 0.5 ) + 0.5;
|
|
237
|
+
uv.y = ( sinTheta * 0.5 * sign ) + 0.5;
|
|
238
|
+
uvs.push( uv.x, uv.y );
|
|
239
|
+
|
|
240
|
+
// increase index
|
|
241
|
+
|
|
242
|
+
index ++;
|
|
243
|
+
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// generate indices
|
|
247
|
+
|
|
248
|
+
for ( let x = 0; x < radialSegments; x ++ ) {
|
|
249
|
+
|
|
250
|
+
const c = centerIndexStart + x;
|
|
251
|
+
const i = centerIndexEnd + x;
|
|
252
|
+
|
|
253
|
+
if ( top === true ) {
|
|
254
|
+
|
|
255
|
+
// face top
|
|
256
|
+
|
|
257
|
+
indices.push( i, i + 1, c );
|
|
258
|
+
|
|
259
|
+
} else {
|
|
260
|
+
|
|
261
|
+
// face bottom
|
|
262
|
+
|
|
263
|
+
indices.push( i + 1, i, c );
|
|
264
|
+
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
groupCount += 3;
|
|
268
|
+
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// add a group to the geometry. this will ensure multi material support
|
|
272
|
+
|
|
273
|
+
scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );
|
|
274
|
+
|
|
275
|
+
// calculate new start value for groups
|
|
276
|
+
|
|
277
|
+
groupStart += groupCount;
|
|
278
|
+
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
*
|
|
287
|
+
* @param {StreamGeometryBuilder} out
|
|
288
|
+
* @param {number} count
|
|
289
|
+
* @param {number} radius
|
|
290
|
+
* @param {number} z
|
|
291
|
+
*/
|
|
292
|
+
function make_ring_vertices(out, count, radius, z) {
|
|
293
|
+
|
|
294
|
+
const positions = out.positions;
|
|
295
|
+
|
|
296
|
+
for (let i = 0; i < count; i++) {
|
|
297
|
+
|
|
298
|
+
const vertex_index = out.cursor_vertices++;
|
|
299
|
+
|
|
300
|
+
const fraction = i / count;
|
|
301
|
+
|
|
302
|
+
const angle = Math.PI * 2 * fraction;
|
|
303
|
+
|
|
304
|
+
const vertex_offset = vertex_index * 3;
|
|
305
|
+
|
|
306
|
+
positions[vertex_offset] = Math.cos(angle) * radius;
|
|
307
|
+
positions[vertex_offset + 1] = Math.sin(angle) * radius;
|
|
308
|
+
positions[vertex_offset + 2] = z;
|
|
309
|
+
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
*
|
|
316
|
+
* @param {StreamGeometryBuilder} out
|
|
317
|
+
* @param {number} count
|
|
318
|
+
* @param {number} vertex_offset
|
|
319
|
+
* @param {number} tip_vertex_index
|
|
320
|
+
*/
|
|
321
|
+
function make_cone_indices(out, count, vertex_offset, tip_vertex_index) {
|
|
322
|
+
const indices = out.indices;
|
|
323
|
+
|
|
324
|
+
for (let i = 0; i < count; i++) {
|
|
325
|
+
const index_0 = i + vertex_offset;
|
|
326
|
+
const index_1 = tip_vertex_index;
|
|
327
|
+
const index_2 = ((i + 1) % count) + vertex_offset;
|
|
328
|
+
|
|
329
|
+
const triangle_index = out.cursor_indices++;
|
|
330
|
+
|
|
331
|
+
const triangle_offset = triangle_index * 3;
|
|
332
|
+
|
|
333
|
+
indices[triangle_offset] = index_1;
|
|
334
|
+
indices[triangle_offset + 1] = index_2;
|
|
335
|
+
indices[triangle_offset + 2] = index_0;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export function makeSolidArrowGeometry(){
|
|
341
|
+
return new ArrowBufferGeometry();
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function makeSolidArrowGeometry2(
|
|
345
|
+
radial_resolution = 16,
|
|
346
|
+
pointer_length = 0.5,
|
|
347
|
+
pointer_width = 0.2,
|
|
348
|
+
stem_width = 0.1
|
|
349
|
+
) {
|
|
350
|
+
|
|
351
|
+
const Z_OFFSET = -0.5;
|
|
352
|
+
|
|
353
|
+
const vertex_count = radial_resolution * 3 + 1;
|
|
354
|
+
|
|
355
|
+
const triangle_count = radial_resolution //arrow cap
|
|
356
|
+
+ radial_resolution * 2 // under-arrow ring
|
|
357
|
+
+ radial_resolution * 2 // stem
|
|
358
|
+
+ radial_resolution //cap for base of the stem
|
|
359
|
+
;
|
|
360
|
+
|
|
361
|
+
const builder = new StreamGeometryBuilder();
|
|
362
|
+
|
|
363
|
+
builder.allocate(vertex_count, triangle_count);
|
|
364
|
+
|
|
365
|
+
const positions = builder.positions;
|
|
366
|
+
|
|
367
|
+
// write tip
|
|
368
|
+
const tip_vertex_index = builder.cursor_vertices++;
|
|
369
|
+
positions[tip_vertex_index * 3] = 0;
|
|
370
|
+
positions[tip_vertex_index * 3 + 1] = 0;
|
|
371
|
+
positions[tip_vertex_index * 3 + 2] = Z_OFFSET + 1;
|
|
372
|
+
|
|
373
|
+
const ring_0_start = builder.cursor_vertices;
|
|
374
|
+
|
|
375
|
+
// make cone ring - arrow cap
|
|
376
|
+
make_ring_vertices(builder, radial_resolution, pointer_width, Z_OFFSET + 1 - pointer_length);
|
|
377
|
+
make_cone_indices(builder, radial_resolution, ring_0_start, tip_vertex_index);
|
|
378
|
+
|
|
379
|
+
const ring_1_start = builder.cursor_vertices;
|
|
380
|
+
|
|
381
|
+
// make ring 1
|
|
382
|
+
make_ring_vertices(builder, radial_resolution, stem_width, Z_OFFSET + 1 - pointer_length);
|
|
383
|
+
make_ring_faces(builder, ring_1_start, 1, radial_resolution);
|
|
384
|
+
|
|
385
|
+
const ring_2_start = builder.cursor_vertices;
|
|
386
|
+
|
|
387
|
+
make_ring_vertices(builder, radial_resolution, stem_width, Z_OFFSET + 0);
|
|
388
|
+
make_ring_faces(builder, ring_2_start, 1, radial_resolution);
|
|
389
|
+
|
|
390
|
+
return builder.build();
|
|
391
|
+
}
|
|
@@ -16,6 +16,17 @@ import { GLTFAssetLoader } from "../../../../asset/loaders/GLTFAssetLoader.js";
|
|
|
16
16
|
import '../../../../../../../../css/game.scss';
|
|
17
17
|
import { countTask } from "../../../../../core/process/task/util/countTask.js";
|
|
18
18
|
import Vector2 from "../../../../../core/geom/Vector2.js";
|
|
19
|
+
import { RotationBehavior } from "../../../../intelligence/behavior/util/RotationBehavior.js";
|
|
20
|
+
import { BehaviorComponent } from "../../../../intelligence/behavior/ecs/BehaviorComponent.js";
|
|
21
|
+
import Vector3 from "../../../../../core/geom/Vector3.js";
|
|
22
|
+
import { ShadedGeometry } from "../../mesh-v2/ShadedGeometry.js";
|
|
23
|
+
import { makeHelperBoxGeometry } from "../../../../../editor/process/symbolic/makeHelperBoxGeometry.js";
|
|
24
|
+
import { DoubleSide, LineBasicMaterial, MeshStandardMaterial } from "three";
|
|
25
|
+
import { DrawMode } from "../../mesh-v2/DrawMode.js";
|
|
26
|
+
import { OctahedralUvEncoder } from "../../../impostors/octahedral/grid/OctahedralUvEncoder.js";
|
|
27
|
+
import { makeSolidArrowGeometry } from "../../../../../editor/process/symbolic/makeSolidArrowGeometry.js";
|
|
28
|
+
import { vec3 } from "gl-matrix";
|
|
29
|
+
import Quaternion from "../../../../../core/geom/Quaternion.js";
|
|
19
30
|
|
|
20
31
|
const decal_urls = `data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_13_t.png
|
|
21
32
|
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_01_t.png
|
|
@@ -217,7 +228,7 @@ function promise_time_out(t) {
|
|
|
217
228
|
* @param {number} spacing
|
|
218
229
|
* @param {string[]} textures
|
|
219
230
|
*/
|
|
220
|
-
function grid(ecd, offset_x, offset_y,x, y, size_x, size_y, spacing, textures) {
|
|
231
|
+
function grid(ecd, offset_x, offset_y, x, y, size_x, size_y, spacing, textures) {
|
|
221
232
|
|
|
222
233
|
const random = seededRandom();
|
|
223
234
|
|
|
@@ -243,7 +254,7 @@ function grid(ecd, offset_x, offset_y,x, y, size_x, size_y, spacing, textures) {
|
|
|
243
254
|
// transform.rotation.set(0,0.7,0,0.7);
|
|
244
255
|
transform.rotation.set(-0.7, 0, 0, 0.7);
|
|
245
256
|
// transform.rotation.random(random);
|
|
246
|
-
transform.scale.set(size_x, size_y,1
|
|
257
|
+
transform.scale.set(size_x, size_y, 1);
|
|
247
258
|
// transform.scale.setScalar(1);
|
|
248
259
|
|
|
249
260
|
entity
|
|
@@ -256,6 +267,97 @@ function grid(ecd, offset_x, offset_y,x, y, size_x, size_y, spacing, textures) {
|
|
|
256
267
|
|
|
257
268
|
}
|
|
258
269
|
|
|
270
|
+
function makeNormalTestGridDecal(ecd, root_transform = new Transform()) {
|
|
271
|
+
const uv = new OctahedralUvEncoder();
|
|
272
|
+
|
|
273
|
+
const GRID_SIZE = 9;
|
|
274
|
+
|
|
275
|
+
const SPACING = 2;
|
|
276
|
+
|
|
277
|
+
const DEBUG_BOX = makeHelperBoxGeometry();
|
|
278
|
+
|
|
279
|
+
for (let i = 0; i < GRID_SIZE; i++) {
|
|
280
|
+
for (let j = 0; j < GRID_SIZE; j++) {
|
|
281
|
+
|
|
282
|
+
const direction = [];
|
|
283
|
+
|
|
284
|
+
uv.uv_to_unit(direction, [i / (GRID_SIZE - 1), j / (GRID_SIZE - 1)]);
|
|
285
|
+
|
|
286
|
+
vec3.negate(direction, direction);
|
|
287
|
+
|
|
288
|
+
const decal = new Decal();
|
|
289
|
+
|
|
290
|
+
decal.uri = decal_urls[1];
|
|
291
|
+
|
|
292
|
+
const entity = new EntityBuilder();
|
|
293
|
+
|
|
294
|
+
entity.clearFlag(EntityBuilderFlags.WatchDestruction);
|
|
295
|
+
|
|
296
|
+
const transform = new Transform();
|
|
297
|
+
transform.position.set(
|
|
298
|
+
SPACING * i,
|
|
299
|
+
SPACING * j,
|
|
300
|
+
0,
|
|
301
|
+
);
|
|
302
|
+
transform.scale.setScalar(1);
|
|
303
|
+
transform.rotation._lookRotation(direction[0],direction[2], direction[1] , 0, 1, 0);
|
|
304
|
+
|
|
305
|
+
transform.multiplyTransforms(root_transform, transform);
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
entity
|
|
309
|
+
.add(ShadedGeometry.from(DEBUG_BOX, new LineBasicMaterial(), DrawMode.LineSegments))
|
|
310
|
+
.add(transform)
|
|
311
|
+
.add(decal)
|
|
312
|
+
.build(ecd);
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
// make an arrow helper
|
|
316
|
+
const arrow_transform = Transform.fromJSON({
|
|
317
|
+
position: new Vector3(0, 0, -0.5)
|
|
318
|
+
});
|
|
319
|
+
arrow_transform.multiplyTransforms(transform, arrow_transform);
|
|
320
|
+
|
|
321
|
+
new EntityBuilder()
|
|
322
|
+
.add(ShadedGeometry.from(makeSolidArrowGeometry(), new MeshStandardMaterial({
|
|
323
|
+
side: DoubleSide
|
|
324
|
+
}), DrawMode.Triangles))
|
|
325
|
+
.add(arrow_transform)
|
|
326
|
+
.build(ecd);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* @returns {EntityBuilder}
|
|
333
|
+
*/
|
|
334
|
+
function makeNormalTestDecal() {
|
|
335
|
+
const decal = new Decal();
|
|
336
|
+
|
|
337
|
+
decal.uri = decal_urls[1];
|
|
338
|
+
|
|
339
|
+
const entity = new EntityBuilder();
|
|
340
|
+
|
|
341
|
+
entity.clearFlag(EntityBuilderFlags.WatchDestruction);
|
|
342
|
+
|
|
343
|
+
const transform = new Transform();
|
|
344
|
+
transform.position.set(
|
|
345
|
+
5,
|
|
346
|
+
0,
|
|
347
|
+
5
|
|
348
|
+
);
|
|
349
|
+
transform.scale.setScalar(1);
|
|
350
|
+
transform.rotation.lookRotation(Vector3.down);
|
|
351
|
+
|
|
352
|
+
entity
|
|
353
|
+
.add(ShadedGeometry.from(DEBUG_BOX, new LineBasicMaterial(), DrawMode.LineSegments))
|
|
354
|
+
.add(transform)
|
|
355
|
+
.add(decal)
|
|
356
|
+
.add(BehaviorComponent.fromOne(RotationBehavior.fromJSON({ speed: 1, axis: Vector3.left })))
|
|
357
|
+
|
|
358
|
+
return entity;
|
|
359
|
+
}
|
|
360
|
+
|
|
259
361
|
/**
|
|
260
362
|
*
|
|
261
363
|
* @param {Engine} engine
|
|
@@ -281,7 +383,9 @@ async function main(engine) {
|
|
|
281
383
|
|
|
282
384
|
const random = seededRandom();
|
|
283
385
|
|
|
284
|
-
const ENTITY_COUNT =
|
|
386
|
+
const ENTITY_COUNT = 1;
|
|
387
|
+
|
|
388
|
+
const ecd = engine.entityManager.dataset;
|
|
285
389
|
|
|
286
390
|
function makeOne() {
|
|
287
391
|
const decal = new Decal();
|
|
@@ -304,9 +408,9 @@ async function main(engine) {
|
|
|
304
408
|
entity
|
|
305
409
|
.add(transform)
|
|
306
410
|
.add(decal)
|
|
307
|
-
|
|
411
|
+
.add(BehaviorComponent.fromOne(RotationBehavior.fromJSON({ speed: 1 })))
|
|
308
412
|
|
|
309
|
-
entity.build(
|
|
413
|
+
entity.build(ecd);
|
|
310
414
|
}
|
|
311
415
|
|
|
312
416
|
// for (let i = 0; i < ENTITY_COUNT; i++) {
|
|
@@ -316,6 +420,33 @@ async function main(engine) {
|
|
|
316
420
|
|
|
317
421
|
const task = countTask(0, ENTITY_COUNT, makeOne);
|
|
318
422
|
|
|
423
|
+
const q_down = new Quaternion();
|
|
424
|
+
q_down.lookRotation(Vector3.down)
|
|
425
|
+
|
|
426
|
+
makeNormalTestGridDecal(ecd, Transform.fromJSON({
|
|
427
|
+
position: new Vector3(5, 0, 5),
|
|
428
|
+
rotation: q_down
|
|
429
|
+
}));
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
const q_forward = new Quaternion();
|
|
433
|
+
q_forward.lookRotation(Vector3.forward)
|
|
434
|
+
|
|
435
|
+
const t_forward_grid = Transform.fromJSON({
|
|
436
|
+
position: new Vector3(5, 4, 5),
|
|
437
|
+
rotation: q_forward
|
|
438
|
+
});
|
|
439
|
+
makeNormalTestGridDecal(ecd, t_forward_grid);
|
|
440
|
+
|
|
441
|
+
new EntityBuilder()
|
|
442
|
+
.add(SGMesh.fromURL('data/models/snaps/cube_white.gltf'))
|
|
443
|
+
.add(Transform.fromJSON({
|
|
444
|
+
position:new Vector3(14,1,4.8),
|
|
445
|
+
rotation: t_forward_grid.rotation,
|
|
446
|
+
scale: new Vector3(25,25,0.1)
|
|
447
|
+
}))
|
|
448
|
+
.build(ecd);
|
|
449
|
+
|
|
319
450
|
// TaskLoadingScreen.instance.load(engine, task);
|
|
320
451
|
|
|
321
452
|
// console.profile('spawn');
|
|
@@ -327,9 +458,9 @@ async function main(engine) {
|
|
|
327
458
|
// engine.executor.run(task);
|
|
328
459
|
|
|
329
460
|
|
|
330
|
-
grid(engine.entityManager.dataset, 20,10,80, 25, .4, .6, .1, decal_urls.slice(105, 105+3));
|
|
461
|
+
//grid(engine.entityManager.dataset, 20,10,80, 25, .4, .6, .1, decal_urls.slice(105, 105+3));
|
|
331
462
|
|
|
332
|
-
grid(engine.entityManager.dataset, 20,30,80, 25, .4, .6, .1, decal_urls.slice(105, 105+3));
|
|
463
|
+
//grid(engine.entityManager.dataset, 20,30,80, 25, .4, .6, .1, decal_urls.slice(105, 105+3));
|
|
333
464
|
// await promise_time_out(10);
|
|
334
465
|
|
|
335
466
|
|
|
@@ -2,7 +2,6 @@ import { AbstractRenderAdapter } from "./AbstractRenderAdapter.js";
|
|
|
2
2
|
import { HashMap } from "../../../../../../core/collection/HashMap.js";
|
|
3
3
|
import { InstancedMeshGroup } from "../../../../geometry/instancing/InstancedMeshGroup.js";
|
|
4
4
|
import { ShadedGeometryFlags } from "../../ShadedGeometryFlags.js";
|
|
5
|
-
import { DrawMode } from "../../DrawMode.js";
|
|
6
5
|
import { StreamDrawUsage } from "three";
|
|
7
6
|
|
|
8
7
|
const INSTANCED_EQUALITY_FLAGS = ShadedGeometryFlags.CastShadow
|
|
@@ -68,14 +67,12 @@ export class InstancedRendererAdapter extends AbstractRenderAdapter {
|
|
|
68
67
|
|
|
69
68
|
} else {
|
|
70
69
|
|
|
71
|
-
if (sg.mode !== DrawMode.Triangles) {
|
|
72
|
-
throw new Error(`Unsupported draw mode ${sg.mode}`);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
70
|
im = new InstancedMeshGroup();
|
|
76
71
|
im.instance_usage = StreamDrawUsage;
|
|
77
72
|
im.shrinkFactor = 0; // prevent shrinking as we're essentially rebuilding this geometry frame
|
|
78
73
|
|
|
74
|
+
im.draw_mode = sg.mode;
|
|
75
|
+
|
|
79
76
|
im.setMaterial(sg.material);
|
|
80
77
|
im.setGeometry(sg.geometry);
|
|
81
78
|
|
|
@@ -60,16 +60,60 @@ export const FP_SHADER_CHUNK_ACCUMULATION = `
|
|
|
60
60
|
// we're inside decal volume
|
|
61
61
|
vec4 light_data_4 = texelFetch(fp_t_light_data, address_to_data_texture_coordinates(light_address+4u), 0);
|
|
62
62
|
|
|
63
|
-
// compute normal of the decal
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
// compute normal of the decal, we get this by extracting rotation matrix and transforming (0,1,0) vector using that
|
|
64
|
+
|
|
65
|
+
mat4 decal_view_transform = viewMatrix*decal_transform_matrix;
|
|
66
|
+
// mat3 decal_view_transform = mat3(transpose(inverse(viewMatrix*decal_transform_matrix)));
|
|
67
|
+
// mat3 decal_view_transform = mat3(transpose(inverse( decal_transform_matrix )));
|
|
68
|
+
|
|
69
|
+
// vec3 decal_normal = normalize(vec3(
|
|
70
|
+
// decal_view_transform[1][0], decal_view_transform[1][1], decal_view_transform[1][2]
|
|
71
|
+
// ));
|
|
72
|
+
|
|
73
|
+
// vec3 decal_normal = normalize(vec3(
|
|
74
|
+
// decal_view_transform[0][2], decal_view_transform[1][2], decal_view_transform[2][2]
|
|
75
|
+
// ));
|
|
76
|
+
vec3 decal_normal = normalize(vec3(
|
|
77
|
+
decal_transform_matrix[0][2], decal_transform_matrix[1][2], decal_transform_matrix[2][2]
|
|
78
|
+
));
|
|
79
|
+
//
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
// vec3 decal_normal = normalize( ( decal_view_transform * vec3( 0.0, 1.0, 0.0 ) ).xyz );
|
|
83
|
+
// vec3 decal_normal = normalize( ( transpose(inverse( decal_view_transform )) * vec4( 0.0, 1.0, 0.0, 0.0 ) ).xyz );
|
|
84
|
+
|
|
85
|
+
// Get geometry normal in world-space
|
|
86
|
+
vec3 g_normal = normalize( ( transpose(viewMatrix) * vec4( geometry.normal, 0.0 ) ).xyz );
|
|
87
|
+
|
|
88
|
+
// material.diffuseColor = geometry.normal*0.5 + 0.5;
|
|
89
|
+
// material.diffuseColor = normalize( ( viewMatrix * vec4( geometry.normal, 0.0 ) ).xyz )*0.5 + 0.5;
|
|
90
|
+
// material.diffuseColor = decal_normal*0.5 + 0.5;
|
|
91
|
+
|
|
92
|
+
// material.diffuseColor = mix(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), decal_normal.y*0.5 + 0.5);
|
|
93
|
+
// material.diffuseColor = mix(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), g_normal.y*0.5 + 0.5);
|
|
94
|
+
// material.diffuseColor = g_normal*0.5 + 0.5;
|
|
95
|
+
// continue;
|
|
96
|
+
|
|
97
|
+
// if(length(local_position.xyz) < 0.3){
|
|
98
|
+
// // circle in the center
|
|
99
|
+
// material.diffuseColor = g_normal*0.5 + 0.5;
|
|
100
|
+
// }else{
|
|
101
|
+
// material.diffuseColor = decal_normal*0.5 + 0.5;
|
|
102
|
+
// }
|
|
103
|
+
//
|
|
104
|
+
// continue;
|
|
105
|
+
|
|
106
|
+
float decal_surface_dot = dot(decal_normal, g_normal);
|
|
107
|
+
|
|
108
|
+
// material.diffuseColor = mix(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), decal_surface_dot);
|
|
109
|
+
// continue;
|
|
66
110
|
|
|
67
111
|
// we fade out decals when the projection angle to the surface gets too steep
|
|
68
112
|
// 0.7 is cos(45deg) and 0.5 is cos(60deg), dot returns cos of angle between two normals
|
|
69
113
|
float decal_surface_angle_fade = smoothstep(-0.5,-0.7,decal_surface_dot);
|
|
70
114
|
|
|
71
115
|
if(decal_surface_angle_fade <= 0.0){
|
|
72
|
-
|
|
116
|
+
continue;
|
|
73
117
|
}
|
|
74
118
|
|
|
75
119
|
vec2 decal_local_uv = (local_position.xy + 0.5);
|
|
@@ -81,7 +125,7 @@ export const FP_SHADER_CHUNK_ACCUMULATION = `
|
|
|
81
125
|
float decal_alpha = decal_color.a * decal_surface_angle_fade;
|
|
82
126
|
|
|
83
127
|
if(decal_alpha < 0.003){
|
|
84
|
-
|
|
128
|
+
continue;
|
|
85
129
|
}
|
|
86
130
|
|
|
87
131
|
material.diffuseColor = material.diffuseColor*(1.0-decal_alpha) + decal_color.xyz*decal_alpha;
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"productName": "Meep",
|
|
6
6
|
"description": "production-ready JavaScript game engine based on Entity Component System Architecture",
|
|
7
7
|
"author": "Alexander Goldring",
|
|
8
|
-
"version": "2.43.
|
|
8
|
+
"version": "2.43.47",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|