@shapediver/viewer.rendering-engine.rendering-engine-threejs 3.3.4 → 3.3.6
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/package.json +19 -20
- package/src/RenderingEngine.ts +0 -1336
- package/src/index.ts +0 -81
- package/src/injectors/Tag3dGeometryCreationInjector.ts +0 -154
- package/src/injectors/TextureUnifierInjector.ts +0 -214
- package/src/interfaces/ILoader.ts +0 -3
- package/src/interfaces/IPostProcessingEffectDefinitions.ts +0 -402
- package/src/interfaces/IRenderingEngine.ts +0 -48
- package/src/loaders/EnvironmentMapLoader.ts +0 -357
- package/src/loaders/GeometryLoader.ts +0 -585
- package/src/loaders/HTMLElementAnchorLoader.ts +0 -107
- package/src/loaders/LightLoader.ts +0 -171
- package/src/loaders/MaterialLoader.ts +0 -1413
- package/src/managers/CameraManager.ts +0 -178
- package/src/managers/EnvironmentGeometryManager.ts +0 -224
- package/src/managers/PostProcessingManager.ts +0 -1181
- package/src/managers/RenderingManager.ts +0 -657
- package/src/managers/SceneTracingManager.ts +0 -127
- package/src/managers/SceneTreeManager.ts +0 -576
- package/src/managers/postprocessing/GodRaysManager.ts +0 -52
- package/src/managers/postprocessing/OutlineManager.ts +0 -58
- package/src/managers/postprocessing/SSAARenderPass.ts +0 -339
- package/src/managers/postprocessing/SelectiveBloomManager.ts +0 -58
- package/src/managers/postprocessing/ao/ao/AOEffect.ts +0 -180
- package/src/managers/postprocessing/ao/ao/AOPass.ts +0 -128
- package/src/managers/postprocessing/ao/ao/shader/ao_compose.glsl +0 -17
- package/src/managers/postprocessing/ao/ao/shader/ao_compose.ts +0 -19
- package/src/managers/postprocessing/ao/hbao/HBAOEffect.ts +0 -41
- package/src/managers/postprocessing/ao/hbao/shader/hbao.glsl +0 -96
- package/src/managers/postprocessing/ao/hbao/shader/hbao.ts +0 -98
- package/src/managers/postprocessing/ao/hbao/shader/hbao_utils.glsl +0 -92
- package/src/managers/postprocessing/ao/hbao/shader/hbao_utils.ts +0 -95
- package/src/managers/postprocessing/ao/poissionDenoise/PoissionDenoisePass.ts +0 -259
- package/src/managers/postprocessing/ao/poissionDenoise/shader/poissionDenoise.glsl +0 -125
- package/src/managers/postprocessing/ao/poissionDenoise/shader/poissionDenoise.ts +0 -127
- package/src/managers/postprocessing/ao/ssao/SSAOEffect.ts +0 -106
- package/src/managers/postprocessing/ao/ssao/shader/ssao.glsl +0 -128
- package/src/managers/postprocessing/ao/ssao/shader/ssao.ts +0 -130
- package/src/managers/postprocessing/ao/utils/shader/basic.glsl +0 -6
- package/src/managers/postprocessing/ao/utils/shader/basic.ts +0 -8
- package/src/managers/postprocessing/ao/utils/shader/sampleBlueNoise.glsl +0 -36
- package/src/managers/postprocessing/ao/utils/shader/sampleBlueNoise.ts +0 -38
- package/src/managers/postprocessing/utils/CopyMaterial.ts +0 -130
- package/src/managers/postprocessing/utils/CopyShader.ts +0 -39
- package/src/managers/postprocessing/utils/FullScreenQuad.ts +0 -47
- package/src/managers/postprocessing/utils/NormalPass.ts +0 -222
- package/src/managers/postprocessing/utils/RenderPass.ts +0 -366
- package/src/materials/GemMaterial.ts +0 -268
- package/src/materials/MeshUnlitMaterialParameters.ts +0 -4
- package/src/materials/MultiPointsMaterial.ts +0 -646
- package/src/materials/SpecularGlossinessMaterial.ts +0 -182
- package/src/objects/SDBone.ts +0 -51
- package/src/objects/SDColor.ts +0 -54
- package/src/objects/SDData.ts +0 -44
- package/src/objects/SDObject.ts +0 -58
- package/src/shaders/PCSS.ts +0 -124
- package/src/shaders/gem.ts +0 -579
- package/src/shaders/gem_frag.glsl +0 -522
- package/src/shaders/gem_vert.glsl +0 -53
- package/src/shaders/multi_points.ts +0 -291
- package/src/shaders/multi_points_frag.glsl +0 -166
- package/src/shaders/multi_points_vert.glsl +0 -120
- package/src/styling/viewport-css.ts +0 -113
- package/src/styling/viewport.css +0 -111
- package/src/three/font.ts +0 -2
- package/src/three/geometries/TextGeometry.ts +0 -58
- package/src/three/loaders/FontLoader.ts +0 -205
- package/src/three/loaders/RGBELoader.ts +0 -496
- package/src/types/IThreejsData.ts +0 -16
- package/src/types/ThreejsData.ts +0 -43
- package/tsconfig.json +0 -20
|
@@ -1,585 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'three';
|
|
2
|
-
import {
|
|
3
|
-
AttributeData,
|
|
4
|
-
GeometryData,
|
|
5
|
-
IAttributeData,
|
|
6
|
-
IMaterialAbstractData,
|
|
7
|
-
IPrimitiveData,
|
|
8
|
-
MATERIAL_SIDE,
|
|
9
|
-
MaterialGemData,
|
|
10
|
-
PRIMITIVE_MODE
|
|
11
|
-
} from '@shapediver/viewer.shared.types';
|
|
12
|
-
import { GemMaterial } from '../materials/GemMaterial';
|
|
13
|
-
import { IBox } from '@shapediver/viewer.shared.math';
|
|
14
|
-
import { ILoader } from '../interfaces/ILoader';
|
|
15
|
-
import { Logger, ShapeDiverViewerDataProcessingError } from '@shapediver/viewer.shared.services';
|
|
16
|
-
import { RENDERER_TYPE } from '@shapediver/viewer.rendering-engine.rendering-engine';
|
|
17
|
-
import { RenderingEngine } from '../RenderingEngine';
|
|
18
|
-
import { SDData } from '../objects/SDData';
|
|
19
|
-
import { vec3 } from 'gl-matrix';
|
|
20
|
-
|
|
21
|
-
export class GeometryLoader implements ILoader {
|
|
22
|
-
// #region Properties (8)
|
|
23
|
-
|
|
24
|
-
private _gemCubeCamera?: THREE.CubeCamera;
|
|
25
|
-
private _gemCubeCameraRenderTarget?: THREE.WebGLCubeRenderTarget;
|
|
26
|
-
private _gemNormalMaterial?: THREE.ShaderMaterial;
|
|
27
|
-
private _gemScene?: THREE.Scene;
|
|
28
|
-
private _gemSphericalMapsCache: {
|
|
29
|
-
[key: string]: {
|
|
30
|
-
texture: THREE.CubeTexture,
|
|
31
|
-
renderTarget: THREE.WebGLCubeRenderTarget,
|
|
32
|
-
counter: number
|
|
33
|
-
}
|
|
34
|
-
} = {};
|
|
35
|
-
private _geometryCache: {
|
|
36
|
-
[key: string]: {
|
|
37
|
-
obj: SDData,
|
|
38
|
-
counter: number
|
|
39
|
-
}
|
|
40
|
-
} = {};
|
|
41
|
-
private _logger: Logger = Logger.instance;
|
|
42
|
-
private _primitiveCache: {
|
|
43
|
-
[key: string]: {
|
|
44
|
-
counter: number,
|
|
45
|
-
threeGeometry: THREE.BufferGeometry,
|
|
46
|
-
clones: THREE.BufferGeometry[]
|
|
47
|
-
}
|
|
48
|
-
} = {};
|
|
49
|
-
|
|
50
|
-
// #endregion Properties (8)
|
|
51
|
-
|
|
52
|
-
// #region Constructors (1)
|
|
53
|
-
|
|
54
|
-
constructor(private readonly _renderingEngine: RenderingEngine) { }
|
|
55
|
-
|
|
56
|
-
// #endregion Constructors (1)
|
|
57
|
-
|
|
58
|
-
// #region Public Methods (7)
|
|
59
|
-
|
|
60
|
-
public emptyGeometryCache() {
|
|
61
|
-
for(const key in this._geometryCache)
|
|
62
|
-
this.removeFromGeometryCache(key);
|
|
63
|
-
this._geometryCache = {};
|
|
64
|
-
|
|
65
|
-
for(const key in this._primitiveCache)
|
|
66
|
-
this.removeFromPrimitiveCache(key);
|
|
67
|
-
this._primitiveCache = {};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
public init(): void { }
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Create a geometry object with the provided geometry data.
|
|
74
|
-
*
|
|
75
|
-
* @param geometry the geometry data
|
|
76
|
-
* @returns the geometry object
|
|
77
|
-
*/
|
|
78
|
-
public load(geometry: GeometryData, parent: SDData, newChild: boolean, skeleton?: THREE.Skeleton): IBox {
|
|
79
|
-
const threeGeometry = (() => {
|
|
80
|
-
if (!this._primitiveCache[geometry.primitive.id + '_' + geometry.primitive.version]) {
|
|
81
|
-
return this.loadPrimitive(geometry.primitive);
|
|
82
|
-
} else {
|
|
83
|
-
this._primitiveCache[geometry.primitive.id + '_' + geometry.primitive.version].counter++;
|
|
84
|
-
const clone = this._primitiveCache[geometry.primitive.id + '_' + geometry.primitive.version].threeGeometry.clone();
|
|
85
|
-
this._primitiveCache[geometry.primitive.id + '_' + geometry.primitive.version].clones.push(clone);
|
|
86
|
-
return clone;
|
|
87
|
-
}
|
|
88
|
-
})();
|
|
89
|
-
|
|
90
|
-
let incomingMaterialData: IMaterialAbstractData | null;
|
|
91
|
-
if (geometry.effectMaterials.length > 0) {
|
|
92
|
-
incomingMaterialData = geometry.effectMaterials[geometry.effectMaterials.length - 1].material;
|
|
93
|
-
} else if (this._renderingEngine.type === RENDERER_TYPE.ATTRIBUTES) {
|
|
94
|
-
incomingMaterialData = geometry.attributeMaterial;
|
|
95
|
-
} else {
|
|
96
|
-
incomingMaterialData = geometry.material;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const materialSettings = {
|
|
100
|
-
mode: geometry.mode,
|
|
101
|
-
useVertexTangents: threeGeometry.attributes.tangent !== undefined,
|
|
102
|
-
useVertexColors: threeGeometry.attributes.color !== undefined && this._renderingEngine.type !== RENDERER_TYPE.ATTRIBUTES,
|
|
103
|
-
useFlatShading: threeGeometry.attributes.normal === undefined,
|
|
104
|
-
useMorphTargets: Object.keys(threeGeometry.morphAttributes).length > 0,
|
|
105
|
-
useMorphNormals: Object.keys(threeGeometry.morphAttributes).length > 0 && threeGeometry.morphAttributes.normal !== undefined
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
if (incomingMaterialData instanceof MaterialGemData) {
|
|
109
|
-
const gemMaterialData = <MaterialGemData>incomingMaterialData;
|
|
110
|
-
threeGeometry.computeBoundingSphere();
|
|
111
|
-
|
|
112
|
-
const sphericalNormalMap = this.createCubeNormalMap(geometry, threeGeometry);
|
|
113
|
-
|
|
114
|
-
const center = threeGeometry.boundingSphere!.center,
|
|
115
|
-
radius = threeGeometry.boundingSphere!.radius;
|
|
116
|
-
|
|
117
|
-
gemMaterialData.side = MATERIAL_SIDE.FRONT;
|
|
118
|
-
|
|
119
|
-
gemMaterialData.center = vec3.fromValues(center.x, center.y, center.z);
|
|
120
|
-
gemMaterialData.radius = radius;
|
|
121
|
-
(<unknown>gemMaterialData.sphericalNormalMap) = sphericalNormalMap;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
while (parent.children.length !== 0)
|
|
125
|
-
parent.remove(parent.children[0]);
|
|
126
|
-
|
|
127
|
-
const material = this._renderingEngine.materialLoader.load(incomingMaterialData || geometry, materialSettings);
|
|
128
|
-
let obj: SDData;
|
|
129
|
-
if (this._geometryCache[geometry.id + '_' + geometry.version] && !skeleton) {
|
|
130
|
-
this._geometryCache[geometry.id + '_' + geometry.version].counter++;
|
|
131
|
-
obj = this._geometryCache[geometry.id + '_' + geometry.version].obj;
|
|
132
|
-
|
|
133
|
-
// case 1: in case the geometry data was cloned and this is a different object
|
|
134
|
-
// case 2: it is a new child
|
|
135
|
-
if (newChild === false && obj.parent !== parent || newChild === true) {
|
|
136
|
-
obj = obj.cloneObject() as SDData;
|
|
137
|
-
parent.add(obj);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
obj.traverse(o => {
|
|
141
|
-
if (
|
|
142
|
-
o instanceof THREE.Points ||
|
|
143
|
-
o instanceof THREE.LineSegments ||
|
|
144
|
-
o instanceof THREE.LineLoop ||
|
|
145
|
-
o instanceof THREE.Line ||
|
|
146
|
-
o instanceof THREE.Mesh)
|
|
147
|
-
o.material = material;
|
|
148
|
-
});
|
|
149
|
-
} else {
|
|
150
|
-
obj = new SDData(geometry.id, geometry.version);
|
|
151
|
-
this.createMesh(obj, geometry, threeGeometry, material, skeleton);
|
|
152
|
-
this._geometryCache[geometry.id + '_' + geometry.version] = { obj, counter: 1 };
|
|
153
|
-
parent.add(obj);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
obj.children.forEach(m => m.castShadow = true);
|
|
157
|
-
if (material instanceof GemMaterial) {
|
|
158
|
-
obj.children.forEach(m => m.receiveShadow = false);
|
|
159
|
-
} else {
|
|
160
|
-
obj.children.forEach(m => m.receiveShadow = true);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return geometry.boundingBox.clone();
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
public loadPrimitive(primitive: IPrimitiveData): THREE.BufferGeometry {
|
|
167
|
-
const geometry = new THREE.BufferGeometry();
|
|
168
|
-
if (primitive.indices)
|
|
169
|
-
geometry.setIndex(new THREE.BufferAttribute(primitive.indices!.array, primitive.indices!.itemSize));
|
|
170
|
-
|
|
171
|
-
for (const attributeId in primitive.attributes) {
|
|
172
|
-
const buffer = this.loadAttribute(primitive.attributes[attributeId], attributeId);
|
|
173
|
-
const attributeName = this.getAttributeName(attributeId);
|
|
174
|
-
|
|
175
|
-
if (attributeId === 'NORMAL')
|
|
176
|
-
if (this.checkNormals(primitive, attributeId, buffer, geometry))
|
|
177
|
-
continue;
|
|
178
|
-
|
|
179
|
-
geometry.setAttribute(attributeName, buffer);
|
|
180
|
-
|
|
181
|
-
const morphAttributeData = primitive.attributes[attributeId].morphAttributeData;
|
|
182
|
-
if (morphAttributeData.length > 0) {
|
|
183
|
-
geometry.morphTargetsRelative = true;
|
|
184
|
-
const buffers: (THREE.BufferAttribute | THREE.InterleavedBufferAttribute)[] = [];
|
|
185
|
-
for (let i = 0; i < morphAttributeData.length; i++)
|
|
186
|
-
buffers.push(this.loadAttribute(morphAttributeData[i], attributeId));
|
|
187
|
-
geometry.morphAttributes[attributeName] = buffers;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// we copy the uv coordinates into the second set of uv coordinates if there are none
|
|
191
|
-
// this allows for the usage of AO and light maps that share this coordinate set
|
|
192
|
-
const attributeIdUV2 = 'TEXCOORD_1', attributeNameUV2 = 'uv1';
|
|
193
|
-
if (attributeName === 'uv' && !primitive.attributes[attributeIdUV2]) {
|
|
194
|
-
geometry.setAttribute(attributeNameUV2, buffer);
|
|
195
|
-
|
|
196
|
-
const morphAttributeData = primitive.attributes[attributeId].morphAttributeData;
|
|
197
|
-
if (morphAttributeData.length > 0) {
|
|
198
|
-
geometry.morphTargetsRelative = true;
|
|
199
|
-
const buffers: (THREE.BufferAttribute | THREE.InterleavedBufferAttribute)[] = [];
|
|
200
|
-
for (let i = 0; i < morphAttributeData.length; i++)
|
|
201
|
-
buffers.push(this.loadAttribute(morphAttributeData[i], attributeId));
|
|
202
|
-
geometry.morphAttributes[attributeNameUV2] = buffers;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
primitive.convertedObject[this._renderingEngine.id] = geometry;
|
|
207
|
-
|
|
208
|
-
this._primitiveCache[primitive.id + '_' + primitive.version] = { threeGeometry: geometry, counter: 1, clones: [] };
|
|
209
|
-
return geometry;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
public removeFromGemSphericalMapsCache(id: string) {
|
|
213
|
-
if (this._gemSphericalMapsCache[id]) {
|
|
214
|
-
if (this._gemSphericalMapsCache[id].counter === 1) {
|
|
215
|
-
this._gemSphericalMapsCache[id].renderTarget.dispose();
|
|
216
|
-
this._gemSphericalMapsCache[id].texture.dispose();
|
|
217
|
-
delete this._gemSphericalMapsCache[id];
|
|
218
|
-
} else {
|
|
219
|
-
this._gemSphericalMapsCache[id].counter--;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
public removeFromGeometryCache(id: string) {
|
|
225
|
-
if (this._geometryCache[id]) {
|
|
226
|
-
if (this._geometryCache[id].counter === 1) {
|
|
227
|
-
this._geometryCache[id].obj.traverse(o => {
|
|
228
|
-
if (o instanceof THREE.Mesh || o instanceof THREE.Points || o instanceof THREE.LineSegments || o instanceof THREE.LineLoop || o instanceof THREE.Line) {
|
|
229
|
-
o.geometry.dispose();
|
|
230
|
-
for (const key in o.geometry.attributes)
|
|
231
|
-
o.geometry.deleteAttribute(key);
|
|
232
|
-
o.geometry.setIndex(null);
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
delete this._geometryCache[id];
|
|
236
|
-
} else {
|
|
237
|
-
this._geometryCache[id].counter--;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
public removeFromPrimitiveCache(id: string) {
|
|
243
|
-
if (this._primitiveCache[id]) {
|
|
244
|
-
if (this._primitiveCache[id].counter === 1) {
|
|
245
|
-
this._primitiveCache[id].threeGeometry.dispose();
|
|
246
|
-
for (const key in this._primitiveCache[id].threeGeometry.attributes)
|
|
247
|
-
this._primitiveCache[id].threeGeometry.deleteAttribute(key);
|
|
248
|
-
this._primitiveCache[id].threeGeometry.setIndex(null);
|
|
249
|
-
|
|
250
|
-
this._primitiveCache[id].clones.forEach(c => {
|
|
251
|
-
c.dispose();
|
|
252
|
-
for (const key in c.attributes)
|
|
253
|
-
c.deleteAttribute(key);
|
|
254
|
-
c.setIndex(null);
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
delete this._primitiveCache[id];
|
|
258
|
-
} else {
|
|
259
|
-
this._primitiveCache[id].counter--;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// #endregion Public Methods (7)
|
|
265
|
-
|
|
266
|
-
// #region Private Methods (6)
|
|
267
|
-
|
|
268
|
-
private checkNormals(primitive: IPrimitiveData, attributeId: string, buffer: THREE.InterleavedBufferAttribute | THREE.BufferAttribute, geometry: THREE.BufferGeometry): boolean {
|
|
269
|
-
let blnNormalsOk = false;
|
|
270
|
-
for (let index = 0; index < 10; ++index) {
|
|
271
|
-
if (Math.abs(buffer.array[index * 3]) > 0.001) {
|
|
272
|
-
blnNormalsOk = true;
|
|
273
|
-
break;
|
|
274
|
-
}
|
|
275
|
-
if (
|
|
276
|
-
Math.abs(buffer.array[index * 3 + 1]) > 0.001
|
|
277
|
-
) {
|
|
278
|
-
blnNormalsOk = true;
|
|
279
|
-
break;
|
|
280
|
-
}
|
|
281
|
-
if (
|
|
282
|
-
Math.abs(buffer.array[index * 3 + 2]) > 0.001
|
|
283
|
-
) {
|
|
284
|
-
blnNormalsOk = true;
|
|
285
|
-
break;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
if (!blnNormalsOk) {
|
|
289
|
-
geometry.computeVertexNormals();
|
|
290
|
-
const computedNormalAttribute = <THREE.BufferAttribute>geometry.getAttribute('normal');
|
|
291
|
-
|
|
292
|
-
// store the computed normals in the attribute data
|
|
293
|
-
primitive.attributes[attributeId] = new AttributeData(
|
|
294
|
-
new Float32Array(computedNormalAttribute.array),
|
|
295
|
-
computedNormalAttribute.itemSize,
|
|
296
|
-
0,
|
|
297
|
-
0,
|
|
298
|
-
3,
|
|
299
|
-
computedNormalAttribute.normalized,
|
|
300
|
-
computedNormalAttribute.array.length / 3);
|
|
301
|
-
return true;
|
|
302
|
-
}
|
|
303
|
-
return false;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
private convertToTriangleMode(geometry: THREE.BufferGeometry, drawMode: PRIMITIVE_MODE) {
|
|
307
|
-
let index = geometry.getIndex();
|
|
308
|
-
// generate index if not present
|
|
309
|
-
if (index === null) {
|
|
310
|
-
const indices = [];
|
|
311
|
-
const position = geometry.getAttribute('position');
|
|
312
|
-
if (position !== undefined) {
|
|
313
|
-
for (let i = 0; i < position.count; i++)
|
|
314
|
-
indices.push(i);
|
|
315
|
-
geometry.setIndex(indices);
|
|
316
|
-
index = geometry.getIndex();
|
|
317
|
-
} else {
|
|
318
|
-
throw new ShapeDiverViewerDataProcessingError('GeometryLoader.convertToTriangleMode: Undefined position attribute. Processing not possible.');
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (index === null)
|
|
323
|
-
throw new ShapeDiverViewerDataProcessingError('GeometryLoader.convertToTriangleMode: Undefined index. Processing not possible.');
|
|
324
|
-
|
|
325
|
-
const numberOfTriangles = index.count - 2;
|
|
326
|
-
const newIndices = [];
|
|
327
|
-
if (drawMode === PRIMITIVE_MODE.TRIANGLE_FAN) {
|
|
328
|
-
for (let i = 1; i <= numberOfTriangles; i++) {
|
|
329
|
-
newIndices.push(index.getX(0));
|
|
330
|
-
newIndices.push(index.getX(i));
|
|
331
|
-
newIndices.push(index.getX(i + 1));
|
|
332
|
-
}
|
|
333
|
-
} else {
|
|
334
|
-
for (let i = 0; i < numberOfTriangles; i++) {
|
|
335
|
-
if (i % 2 === 0) {
|
|
336
|
-
newIndices.push(index.getX(i));
|
|
337
|
-
newIndices.push(index.getX(i + 1));
|
|
338
|
-
newIndices.push(index.getX(i + 2));
|
|
339
|
-
} else {
|
|
340
|
-
newIndices.push(index.getX(i + 2));
|
|
341
|
-
newIndices.push(index.getX(i + 1));
|
|
342
|
-
newIndices.push(index.getX(i));
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if ((newIndices.length / 3) !== numberOfTriangles)
|
|
348
|
-
throw new ShapeDiverViewerDataProcessingError('GeometryLoader.convertToTriangleMode: Unable to generate correct amount of triangle.');
|
|
349
|
-
|
|
350
|
-
geometry.setIndex(newIndices);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
private createCubeNormalMap(geometryData: GeometryData, geometry: THREE.BufferGeometry, resolution = 1024) {
|
|
354
|
-
if (this._gemSphericalMapsCache[geometryData.primitive.id + '_' + geometryData.primitive.version]) {
|
|
355
|
-
this._gemSphericalMapsCache[geometryData.primitive.id + '_' + geometryData.primitive.version].counter++;
|
|
356
|
-
return this._gemSphericalMapsCache[geometryData.primitive.id + '_' + geometryData.primitive.version].texture;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
if (!this._gemScene) {
|
|
360
|
-
this._gemScene = new THREE.Scene();
|
|
361
|
-
this._gemCubeCameraRenderTarget = new THREE.WebGLCubeRenderTarget(resolution, { format: THREE.RGBAFormat, magFilter: THREE.LinearFilter, minFilter: THREE.LinearFilter });
|
|
362
|
-
this._gemCubeCameraRenderTarget.texture.generateMipmaps = false;
|
|
363
|
-
this._gemCubeCameraRenderTarget.texture.minFilter = THREE.NearestFilter;
|
|
364
|
-
this._gemCubeCameraRenderTarget.texture.magFilter = THREE.NearestFilter;
|
|
365
|
-
this._gemCubeCameraRenderTarget.texture.format = THREE.RGBAFormat;
|
|
366
|
-
this._gemCubeCamera = new THREE.CubeCamera(0.001, 10000, this._gemCubeCameraRenderTarget);
|
|
367
|
-
this._gemScene.add(this._gemCubeCamera);
|
|
368
|
-
} else {
|
|
369
|
-
this._gemCubeCameraRenderTarget = new THREE.WebGLCubeRenderTarget(resolution, { format: THREE.RGBAFormat, magFilter: THREE.LinearFilter, minFilter: THREE.LinearFilter });
|
|
370
|
-
this._gemCubeCameraRenderTarget.texture.generateMipmaps = false;
|
|
371
|
-
this._gemCubeCameraRenderTarget.texture.minFilter = THREE.NearestFilter;
|
|
372
|
-
this._gemCubeCameraRenderTarget.texture.magFilter = THREE.NearestFilter;
|
|
373
|
-
this._gemCubeCameraRenderTarget.texture.format = THREE.RGBAFormat;
|
|
374
|
-
this._gemCubeCamera!.renderTarget = this._gemCubeCameraRenderTarget;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
if (!this._gemNormalMaterial) {
|
|
378
|
-
const _normalShader = {
|
|
379
|
-
defines: {},
|
|
380
|
-
uniforms: THREE.UniformsUtils.merge([
|
|
381
|
-
THREE.UniformsLib.common]),
|
|
382
|
-
vertexShader: `
|
|
383
|
-
varying vec3 vNormal;
|
|
384
|
-
|
|
385
|
-
void main() {
|
|
386
|
-
vNormal = normal;
|
|
387
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
|
388
|
-
}
|
|
389
|
-
`,
|
|
390
|
-
fragmentShader: `
|
|
391
|
-
varying highp vec3 vNormal;
|
|
392
|
-
|
|
393
|
-
float decodeFloat(float f) {
|
|
394
|
-
float r = mod(f, 1.0/255.0);
|
|
395
|
-
return /*r > 0.5/256.0 ? f + (1.0/256.0) - r : */f - r;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
vec3 decodeVec3(vec3 v) {
|
|
399
|
-
return vec3(decodeFloat(v.x), decodeFloat(v.y), decodeFloat(v.z));
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
float signEncoding(vec3 v) {
|
|
403
|
-
float code = 1.0;
|
|
404
|
-
if(v.x < 0.0 && v.y < 0.0 && v.z < 0.0) {
|
|
405
|
-
code = 0.0;
|
|
406
|
-
} else if (v.x < 0.0 && v.y < 0.0) {
|
|
407
|
-
code = 2.0/256.0;
|
|
408
|
-
} else if (v.x < 0.0 && v.z < 0.0) {
|
|
409
|
-
code = 4.0/256.0;
|
|
410
|
-
} else if (v.y < 0.0 && v.z < 0.0) {
|
|
411
|
-
code = 6.0/256.0;
|
|
412
|
-
} else if (v.x < 0.0) {
|
|
413
|
-
code = 8.0/256.0;
|
|
414
|
-
} else if (v.y < 0.0) {
|
|
415
|
-
code = 10.0/256.0;
|
|
416
|
-
} else if (v.z < 0.0) {
|
|
417
|
-
code = 12.0/256.0;
|
|
418
|
-
}
|
|
419
|
-
return code;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
void main() {
|
|
423
|
-
vec3 n = normalize(vNormal);
|
|
424
|
-
gl_FragColor = vec4(decodeVec3(abs(n)), signEncoding(n));
|
|
425
|
-
}
|
|
426
|
-
`
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
this._gemNormalMaterial = new THREE.ShaderMaterial({
|
|
430
|
-
uniforms: THREE.UniformsUtils.clone(_normalShader.uniforms),
|
|
431
|
-
defines: _normalShader.defines,
|
|
432
|
-
vertexShader: _normalShader.vertexShader,
|
|
433
|
-
fragmentShader: _normalShader.fragmentShader
|
|
434
|
-
});
|
|
435
|
-
|
|
436
|
-
this._gemNormalMaterial.blending = THREE.NoBlending;
|
|
437
|
-
this._gemNormalMaterial.side = THREE.DoubleSide;
|
|
438
|
-
this._gemScene.overrideMaterial = this._gemNormalMaterial;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
const mesh = new THREE.Mesh(geometry.clone(), this._gemNormalMaterial);
|
|
442
|
-
mesh.geometry.center();
|
|
443
|
-
this._gemScene.add(mesh);
|
|
444
|
-
|
|
445
|
-
this._gemCubeCamera!.update(this._renderingEngine.renderer, this._gemScene);
|
|
446
|
-
this._gemScene.remove(mesh);
|
|
447
|
-
mesh.geometry.dispose();
|
|
448
|
-
mesh.material.dispose();
|
|
449
|
-
|
|
450
|
-
this._gemCubeCamera!.renderTarget.texture.userData = {
|
|
451
|
-
SDid: geometryData.primitive.id,
|
|
452
|
-
SDversion: geometryData.primitive.version
|
|
453
|
-
};
|
|
454
|
-
|
|
455
|
-
this._gemSphericalMapsCache[geometryData.primitive.id + '_' + geometryData.primitive.version] = { texture: this._gemCubeCameraRenderTarget.texture, renderTarget: this._gemCubeCameraRenderTarget, counter: 1 };
|
|
456
|
-
return this._gemSphericalMapsCache[geometryData.primitive.id + '_' + geometryData.primitive.version].texture;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
private createMesh(obj: SDData, geometry: GeometryData, threeGeometry: THREE.BufferGeometry, material: THREE.Material, skeleton?: THREE.Skeleton) {
|
|
460
|
-
if (geometry.mode === PRIMITIVE_MODE.POINTS) {
|
|
461
|
-
const points = new THREE.Points(threeGeometry, material);
|
|
462
|
-
geometry.convertedObject[this._renderingEngine.id] = points;
|
|
463
|
-
obj.add(points);
|
|
464
|
-
} else if (geometry.mode === PRIMITIVE_MODE.LINES) {
|
|
465
|
-
const lineSegments = new THREE.LineSegments(threeGeometry, material);
|
|
466
|
-
geometry.convertedObject[this._renderingEngine.id] = lineSegments;
|
|
467
|
-
obj.add(lineSegments);
|
|
468
|
-
} else if (geometry.mode === PRIMITIVE_MODE.LINE_LOOP) {
|
|
469
|
-
const lineLoop = new THREE.LineLoop(threeGeometry, material);
|
|
470
|
-
geometry.convertedObject[this._renderingEngine.id] = lineLoop;
|
|
471
|
-
obj.add(lineLoop);
|
|
472
|
-
} else if (geometry.mode === PRIMITIVE_MODE.LINE_STRIP) {
|
|
473
|
-
const line = new THREE.Line(threeGeometry, material);
|
|
474
|
-
geometry.convertedObject[this._renderingEngine.id] = line;
|
|
475
|
-
obj.add(line);
|
|
476
|
-
} else if (geometry.mode === PRIMITIVE_MODE.TRIANGLES || geometry.mode === PRIMITIVE_MODE.TRIANGLE_STRIP || geometry.mode === PRIMITIVE_MODE.TRIANGLE_FAN) {
|
|
477
|
-
const bufferGeometry = threeGeometry;
|
|
478
|
-
if (geometry.mode === PRIMITIVE_MODE.TRIANGLE_STRIP || geometry.mode === PRIMITIVE_MODE.TRIANGLE_FAN)
|
|
479
|
-
this.convertToTriangleMode(bufferGeometry, geometry.mode);
|
|
480
|
-
|
|
481
|
-
if (skeleton) {
|
|
482
|
-
const skinnedMesh = new THREE.SkinnedMesh(bufferGeometry, material);
|
|
483
|
-
geometry.convertedObject[this._renderingEngine.id] = skinnedMesh;
|
|
484
|
-
skinnedMesh.bind(skeleton, skinnedMesh.matrixWorld);
|
|
485
|
-
|
|
486
|
-
if ((<THREE.BufferAttribute>bufferGeometry.attributes.skinWeight).normalized)
|
|
487
|
-
skinnedMesh.normalizeSkinWeights();
|
|
488
|
-
|
|
489
|
-
obj.add(skinnedMesh);
|
|
490
|
-
} else {
|
|
491
|
-
const mesh = new THREE.Mesh(bufferGeometry, material);
|
|
492
|
-
geometry.convertedObject[this._renderingEngine.id] = mesh;
|
|
493
|
-
obj.add(mesh);
|
|
494
|
-
}
|
|
495
|
-
} else {
|
|
496
|
-
throw new ShapeDiverViewerDataProcessingError(`GeometryLoader.load: Unrecognized primitive mode ${geometry.mode}.`);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
obj.traverse(m => {
|
|
500
|
-
if (m instanceof THREE.Mesh || m instanceof THREE.Points || m instanceof THREE.LineSegments || m instanceof THREE.LineLoop || m instanceof THREE.Line) {
|
|
501
|
-
(<THREE.Mesh>m).geometry.userData = {
|
|
502
|
-
SDid: geometry.id,
|
|
503
|
-
SDversion: geometry.version,
|
|
504
|
-
primitiveSDid: geometry.primitive.id,
|
|
505
|
-
primitiveSDversion: geometry.primitive.version
|
|
506
|
-
};
|
|
507
|
-
m.renderOrder = geometry.renderOrder;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
if (m instanceof THREE.Mesh && m.userData.transparencyPlaceholder !== true) {
|
|
511
|
-
(<THREE.Mesh>m).geometry.boundingBox = new THREE.Box3(new THREE.Vector3(geometry.boundingBox.min[0], geometry.boundingBox.min[1], geometry.boundingBox.min[2]), new THREE.Vector3(geometry.boundingBox.max[0], geometry.boundingBox.max[1], geometry.boundingBox.max[2]));
|
|
512
|
-
(<THREE.Mesh>m).geometry.boundingSphere = new THREE.Sphere(new THREE.Vector3(geometry.boundingBox.boundingSphere.center[0], geometry.boundingBox.boundingSphere.center[1], geometry.boundingBox.boundingSphere.center[2]), geometry.boundingBox.boundingSphere.radius);
|
|
513
|
-
(<THREE.Mesh>m).morphTargetInfluences = geometry.morphWeights;
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
private getAttributeName(attributeId: string): string {
|
|
519
|
-
switch (attributeId) {
|
|
520
|
-
case 'POSITION':
|
|
521
|
-
return 'position';
|
|
522
|
-
case 'NORMAL':
|
|
523
|
-
return 'normal';
|
|
524
|
-
case 'TEXCOORD_0':
|
|
525
|
-
case 'TEXCOORD0':
|
|
526
|
-
case 'TEXCOORD':
|
|
527
|
-
case 'UV':
|
|
528
|
-
return 'uv';
|
|
529
|
-
case 'TEXCOORD_1':
|
|
530
|
-
return 'uv1';
|
|
531
|
-
case 'TEXCOORD_2':
|
|
532
|
-
return 'uv2';
|
|
533
|
-
case 'TEXCOORD_3':
|
|
534
|
-
return 'uv3';
|
|
535
|
-
case 'COLOR_0':
|
|
536
|
-
case 'COLOR0':
|
|
537
|
-
case 'COLOR':
|
|
538
|
-
return 'color';
|
|
539
|
-
case 'WEIGHT':
|
|
540
|
-
case 'WEIGHTS_0':
|
|
541
|
-
return 'skinWeight';
|
|
542
|
-
case 'JOINT':
|
|
543
|
-
case 'JOINTS_0':
|
|
544
|
-
return 'skinIndex';
|
|
545
|
-
case 'TANGENT':
|
|
546
|
-
return 'tangent';
|
|
547
|
-
case 'POSITION_INDEX':
|
|
548
|
-
return 'positionIndex';
|
|
549
|
-
default:
|
|
550
|
-
this._logger.warn(`GeometryLoader.loadPrimitive: Unrecognized attribute id ${attributeId}.`);
|
|
551
|
-
}
|
|
552
|
-
return '';
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
private loadAttribute(bufferAttribute: IAttributeData, attributeId: string) {
|
|
556
|
-
let buffer: THREE.InterleavedBufferAttribute | THREE.BufferAttribute;
|
|
557
|
-
|
|
558
|
-
if (bufferAttribute.byteStride && bufferAttribute.byteStride !== bufferAttribute.itemBytes) {
|
|
559
|
-
// Integer parameters to IB/IBA are in array elements, not bytes.
|
|
560
|
-
const ib = new THREE.InterleavedBuffer(bufferAttribute.array, bufferAttribute.byteStride / bufferAttribute.elementBytes);
|
|
561
|
-
buffer = new THREE.InterleavedBufferAttribute(ib, bufferAttribute.itemSize, (bufferAttribute.byteOffset % bufferAttribute.byteStride) / bufferAttribute.elementBytes, bufferAttribute.normalized);
|
|
562
|
-
} else {
|
|
563
|
-
buffer = new THREE.BufferAttribute(bufferAttribute.array, bufferAttribute.itemSize, (attributeId === 'COLOR_0' || attributeId === 'COLOR0' || attributeId === 'COLOR') ? true : bufferAttribute.normalized);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
if (bufferAttribute.sparse) {
|
|
567
|
-
if (bufferAttribute.array !== null) {
|
|
568
|
-
// Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes.
|
|
569
|
-
buffer = new THREE.BufferAttribute(bufferAttribute.array.slice(), bufferAttribute.itemSize, bufferAttribute.normalized);
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
for (let i = 0, il = bufferAttribute.sparseIndices!.length; i < il; i++) {
|
|
573
|
-
const index = bufferAttribute.sparseIndices![i];
|
|
574
|
-
buffer.setX(index, bufferAttribute.sparseValues![i * bufferAttribute.itemSize]);
|
|
575
|
-
if (bufferAttribute.itemSize >= 2) buffer.setY(index, bufferAttribute.sparseValues![i * bufferAttribute.itemSize + 1]);
|
|
576
|
-
if (bufferAttribute.itemSize >= 3) buffer.setZ(index, bufferAttribute.sparseValues![i * bufferAttribute.itemSize + 2]);
|
|
577
|
-
if (bufferAttribute.itemSize >= 4) buffer.setW(index, bufferAttribute.sparseValues![i * bufferAttribute.itemSize + 3]);
|
|
578
|
-
if (bufferAttribute.itemSize >= 5) throw new ShapeDiverViewerDataProcessingError('GeometryLoader.loadPrimitive: Unsupported itemSize in sparse BufferAttribute.');
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
return buffer;
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
// #endregion Private Methods (6)
|
|
585
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { BUSY_MODE_DISPLAY } from '@shapediver/viewer.rendering-engine.rendering-engine';
|
|
2
|
-
import { HTMLElementAnchorData } from '@shapediver/viewer.shared.types';
|
|
3
|
-
import { ILoader } from '../interfaces/ILoader';
|
|
4
|
-
import { ITreeNode } from '@shapediver/viewer.shared.node-tree';
|
|
5
|
-
import { RenderingEngine } from '../RenderingEngine';
|
|
6
|
-
import { vec2, vec3 } from 'gl-matrix';
|
|
7
|
-
|
|
8
|
-
export class HTMLElementAnchorLoader implements ILoader {
|
|
9
|
-
// #region Properties (2)
|
|
10
|
-
|
|
11
|
-
private readonly _htmlElements: {
|
|
12
|
-
[key: string]: {
|
|
13
|
-
anchor: HTMLElementAnchorData,
|
|
14
|
-
node: ITreeNode
|
|
15
|
-
}
|
|
16
|
-
} = {};
|
|
17
|
-
private readonly _parentDiv: HTMLDivElement;
|
|
18
|
-
|
|
19
|
-
// #endregion Properties (2)
|
|
20
|
-
|
|
21
|
-
// #region Constructors (1)
|
|
22
|
-
|
|
23
|
-
constructor(private readonly _renderingEngine: RenderingEngine) {
|
|
24
|
-
this._parentDiv = document.createElement('div');
|
|
25
|
-
this._parentDiv.classList.add('sdv-anchor-container');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// #endregion Constructors (1)
|
|
29
|
-
|
|
30
|
-
// #region Public Getters And Setters (1)
|
|
31
|
-
|
|
32
|
-
public get parentDiv(): HTMLDivElement {
|
|
33
|
-
return this._parentDiv;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// #endregion Public Getters And Setters (1)
|
|
37
|
-
|
|
38
|
-
// #region Public Methods (5)
|
|
39
|
-
|
|
40
|
-
public adjustPositions(scaleWidth: number, scaleHeight: number): void {
|
|
41
|
-
for (const anchorId in this._htmlElements) {
|
|
42
|
-
const anchor = this._htmlElements[anchorId].anchor;
|
|
43
|
-
const { page, container, client, hidden } = this._renderingEngine.sceneTracingManager.convert3Dto2D(vec3.clone(anchor.location));
|
|
44
|
-
|
|
45
|
-
const htmlElement = anchor.createViewerHtmlElement(this._renderingEngine.id);
|
|
46
|
-
if (!htmlElement) continue;
|
|
47
|
-
|
|
48
|
-
let node = this._htmlElements[anchorId].node;
|
|
49
|
-
|
|
50
|
-
let visible = node.visible;
|
|
51
|
-
while (node.parent) {
|
|
52
|
-
node = node.parent;
|
|
53
|
-
visible = node.visible && visible;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (this._renderingEngine.show === false)
|
|
57
|
-
visible = false;
|
|
58
|
-
|
|
59
|
-
anchor.update({ anchor, htmlElement, page, container, client, scale: vec2.fromValues(scaleWidth, scaleHeight), hidden, visible });
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public init(): void {
|
|
64
|
-
this._renderingEngine.canvas.parentNode?.appendChild(this._parentDiv);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public load(node: ITreeNode, anchor: HTMLElementAnchorData, isVisibleInHierarchy: boolean): void {
|
|
68
|
-
const htmlElement = anchor.createViewerHtmlElement(this._renderingEngine.id);
|
|
69
|
-
if (!htmlElement) return;
|
|
70
|
-
|
|
71
|
-
// set the display property to "none" if the viewport is not shown or the node is not visible
|
|
72
|
-
if (this._renderingEngine.show === false || isVisibleInHierarchy === false) htmlElement.style.display = 'none';
|
|
73
|
-
|
|
74
|
-
// if the node is not visible return
|
|
75
|
-
if (isVisibleInHierarchy === false) return;
|
|
76
|
-
|
|
77
|
-
this._parentDiv.appendChild(htmlElement);
|
|
78
|
-
this._htmlElements[anchor.id + '_' + anchor.version] = {
|
|
79
|
-
node,
|
|
80
|
-
anchor
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
public removeData(id: string, version: string) {
|
|
85
|
-
// since the data object might be there, but no data is loaded for this viewport
|
|
86
|
-
// this check is needed
|
|
87
|
-
if (!this._htmlElements[id + '_' + version]) return;
|
|
88
|
-
|
|
89
|
-
const anchor = this._htmlElements[id + '_' + version].anchor;
|
|
90
|
-
if (anchor && anchor.getViewerHtmlElement(this._renderingEngine.id)) {
|
|
91
|
-
this._parentDiv.removeChild(anchor.getViewerHtmlElement(this._renderingEngine.id)!);
|
|
92
|
-
delete this._htmlElements[id + '_' + version];
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
public toggleBusyMode(toggle: boolean) {
|
|
97
|
-
if (toggle && this._renderingEngine.busyModeDisplay === BUSY_MODE_DISPLAY.BLUR) {
|
|
98
|
-
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1 && navigator.userAgent.toLowerCase().indexOf('android') > -1)
|
|
99
|
-
return;
|
|
100
|
-
this._parentDiv.style.filter = 'blur(3px)';
|
|
101
|
-
} else {
|
|
102
|
-
this._parentDiv.style.filter = '';
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// #endregion Public Methods (5)
|
|
107
|
-
}
|