@tomorrowevening/hermes 0.0.27 → 0.0.29

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.
@@ -1,51 +1,102 @@
1
+ import { AnimationMixer } from 'three';
1
2
  import RemoteThree from '@/core/remote/RemoteThree';
2
3
  import InspectorGroup from '../InspectorGroup';
3
- import { InspectorFieldProps } from '../InspectorField';
4
4
  import { AnimationClipInfo, RemoteObject } from '../../types';
5
- import { setItemProps } from '../../utils';
6
5
 
7
6
  export default function InspectAnimation(obj: RemoteObject, three: RemoteThree) {
8
- const items: InspectorFieldProps[] = [];
9
- obj.animations.forEach((value: AnimationClipInfo) => {
7
+ const items: any[] = [];
8
+ const animations: any[] = [];
9
+ let maxDuration = 0;
10
+ obj.animations.forEach((clipInfo: AnimationClipInfo) => {
10
11
  // Add animation
11
- items.push({
12
- title: 'Name',
13
- type: 'string',
14
- prop: 'name',
15
- value: value.name,
16
- disabled: true,
17
- onChange: (prop: string, value: any) => {
18
- three.updateObject(obj.uuid, prop, value);
19
- const child = three.scene?.getObjectByProperty('uuid', obj.uuid);
20
- if (child !== undefined) setItemProps(child, prop, value);
21
- },
22
- });
23
- items.push({
24
- title: 'Duration',
25
- type: 'number',
26
- prop: 'duration',
27
- value: value.duration,
28
- disabled: true,
29
- onChange: (prop: string, value: any) => {
30
- three.updateObject(obj.uuid, prop, value);
31
- const child = three.scene?.getObjectByProperty('uuid', obj.uuid);
32
- if (child !== undefined) setItemProps(child, prop, value);
33
- },
34
- });
35
- items.push({
36
- title: 'Blend Mode',
37
- type: 'number',
38
- prop: 'blendMode',
39
- value: value.blendMode,
40
- disabled: true,
41
- onChange: (prop: string, value: any) => {
42
- three.updateObject(obj.uuid, prop, value);
43
- const child = three.scene?.getObjectByProperty('uuid', obj.uuid);
44
- if (child !== undefined) setItemProps(child, prop, value);
45
- },
46
- });
12
+ maxDuration = Math.max(maxDuration, clipInfo.duration);
13
+ if (clipInfo.duration > 0) {
14
+ animations.push({
15
+ title: clipInfo.name,
16
+ items: [
17
+ {
18
+ title: 'Duration',
19
+ type: 'number',
20
+ value: clipInfo.duration,
21
+ disabled: true,
22
+ },
23
+ {
24
+ title: 'Blend Mode',
25
+ type: 'option',
26
+ disabled: true,
27
+ options: [
28
+ {
29
+ title: 'Normal',
30
+ value: 2500,
31
+ },
32
+ {
33
+ title: 'Additive',
34
+ value: 2501,
35
+ },
36
+ ],
37
+ }
38
+ ]
39
+ });
40
+ }
47
41
  });
42
+ items.push({
43
+ title: 'Animations',
44
+ items: animations
45
+ });
46
+
47
+ const child = three.scene?.getObjectByProperty('uuid', obj.uuid);
48
+ let hasMixer = false;
49
+ if (child !== undefined) {
50
+ const mixer = child['mixer'] as AnimationMixer;
51
+ hasMixer = mixer !== undefined;
52
+ if (hasMixer) {
53
+ const mixerItems: any[] = [
54
+ {
55
+ title: 'Time Scale',
56
+ type: 'range',
57
+ value: mixer.timeScale,
58
+ step: 0.01,
59
+ min: -1,
60
+ max: 2,
61
+ onChange: (_: string, value: any) => {
62
+ mixer.timeScale = value;
63
+ three.updateObject(obj.uuid, 'mixer.timeScale', value);
64
+ },
65
+ },
66
+ ];
67
+ // animations.forEach((animation: any, index: number) => {
68
+ // if (obj.animations[index].duration > 0) {
69
+ // mixerItems.push({
70
+ // title: `Play: ${animation.title}`,
71
+ // type: 'button',
72
+ // onChange: () => {
73
+ // // Stop Previous
74
+ // mixer.stopAllAction();
75
+ // three.requestMethod(obj.uuid, 'stopAllAction', undefined, 'mixer');
76
+
77
+ // //
78
+ // const clip = child.animations[index] as AnimationClip;
79
+ // const action = mixer.clipAction(clip);
80
+ // action.play();
81
+ // }
82
+ // });
83
+ // }
84
+ // });
85
+ mixerItems.push({
86
+ title: 'Stop All',
87
+ type: 'button',
88
+ onChange: () => {
89
+ mixer.stopAllAction();
90
+ three.requestMethod(obj.uuid, 'stopAllAction', undefined, 'mixer');
91
+ }
92
+ });
93
+ items.push({
94
+ title: 'Mixer',
95
+ items: mixerItems
96
+ });
97
+ }
98
+ }
48
99
  return (
49
- <InspectorGroup title='Animations' items={items} />
100
+ <InspectorGroup title='Animation' items={items} />
50
101
  );
51
102
  }
@@ -1,14 +1,16 @@
1
- import { Color, Texture } from 'three';
1
+ import { AddEquation, AdditiveBlending, BackSide, Color, ConstantAlphaFactor, ConstantColorFactor, CustomBlending, DoubleSide, DstAlphaFactor, DstColorFactor, FrontSide, MaxEquation, MinEquation, MultiplyBlending, NoBlending, NormalBlending, OneFactor, OneMinusConstantAlphaFactor, OneMinusConstantColorFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, ReverseSubtractEquation, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, SubtractEquation, SubtractiveBlending, Texture, ZeroFactor } from 'three';
2
2
  import InspectorGroup from '../InspectorGroup';
3
3
  import { RemoteMaterial, RemoteObject } from '../../types';
4
4
  import RemoteThree from '@/core/remote/RemoteThree';
5
5
  import { setItemProps, textureFromSrc } from '../../utils';
6
+ import { capitalize } from '@/editor/utils';
6
7
 
7
8
  export function acceptedMaterialNames(name: string): boolean {
8
9
  return !(
9
10
  name === 'alphaHash' ||
10
11
  name === 'alphaToCoverage' ||
11
12
  name === 'attenuationDistance' ||
13
+ name === 'blendDstAlpha' ||
12
14
  name === 'colorWrite' ||
13
15
  name === 'combine' ||
14
16
  name === 'defaultAttributeValues' ||
@@ -22,7 +24,6 @@ export function acceptedMaterialNames(name: string): boolean {
22
24
  name === 'precision' ||
23
25
  name === 'premultipliedAlpha' ||
24
26
  name === 'shadowSide' ||
25
- name === 'side' ||
26
27
  name === 'toneMapped' ||
27
28
  name === 'uniformsGroups' ||
28
29
  name === 'uniformsNeedUpdate' ||
@@ -32,7 +33,6 @@ export function acceptedMaterialNames(name: string): boolean {
32
33
  name === 'wireframeLinecap' ||
33
34
  name === 'wireframeLinejoin' ||
34
35
  name === 'wireframeLinewidth' ||
35
- name.slice(0, 5) === 'blend' ||
36
36
  name.slice(0, 4) === 'clip' ||
37
37
  name.slice(0, 7) === 'polygon' ||
38
38
  name.slice(0, 7) === 'stencil' ||
@@ -48,6 +48,15 @@ export function prettyName(name: string): string {
48
48
  case 'aoMap': return 'AO Map';
49
49
  case 'aoMapIntensity': return 'AO Map Intensity';
50
50
  case 'attenuationColor': return 'Attenuation Color';
51
+ case 'blendAlpha': return 'Blend Alpha';
52
+ case 'blendColor': return 'Blend Color';
53
+ case 'blendDst': return 'Blend Dst';
54
+ case 'blendDstAlpha': return 'Blend Dst Alha';
55
+ case 'blendEquation': return 'Blend Equation';
56
+ case 'blendEquationAlpha': return 'Blend Equation Alpha';
57
+ case 'blending': return 'Blending';
58
+ case 'blendSrc': return 'Blend Src';
59
+ case 'blendSrcAlpha': return 'Blend Src Alpha';
51
60
  case 'bumpMap': return 'Bump Map';
52
61
  case 'bumpScale': return 'Bump Scale';
53
62
  case 'clearcoatMap': return 'Clearcoat Map';
@@ -98,6 +107,7 @@ export function prettyName(name: string): string {
98
107
  case 'sheenRoughness': return 'Sheen Roughness';
99
108
  case 'sheenRoughnessMap': return 'Sheen Roughness Map';
100
109
  case 'shininess': return 'Shininess';
110
+ case 'side': return 'Side';
101
111
  case 'size': return 'Size';
102
112
  case 'sizeAttenuation': return 'Size Attenuation';
103
113
  case 'specular': return 'Specular';
@@ -124,6 +134,7 @@ export function clampedNames(name: string): boolean {
124
134
  return (
125
135
  name.toLowerCase().search('intensity') > -1 ||
126
136
  name === 'anisotropyRotation' ||
137
+ name === 'blendAlpha' ||
127
138
  name === 'bumpScale' ||
128
139
  name === 'clearcoatRoughness' ||
129
140
  name === 'displacementBias' ||
@@ -158,6 +169,205 @@ export function uploadLocalImage(): Promise<string> {
158
169
  });
159
170
  }
160
171
 
172
+ // Material side
173
+
174
+ const materialSideOpts: any[] = [
175
+ {
176
+ title: 'Front',
177
+ value: FrontSide,
178
+ },
179
+ {
180
+ title: 'Back',
181
+ value: BackSide,
182
+ },
183
+ {
184
+ title: 'Double',
185
+ value: DoubleSide,
186
+ },
187
+ ];
188
+
189
+ // Blending
190
+
191
+ const blendingOpts: any[] = [
192
+ {
193
+ title: 'No Blending',
194
+ value: NoBlending,
195
+ },
196
+ {
197
+ title: 'Normal',
198
+ value: NormalBlending,
199
+ },
200
+ {
201
+ title: 'Additive',
202
+ value: AdditiveBlending,
203
+ },
204
+ {
205
+ title: 'Subtractive',
206
+ value: SubtractiveBlending,
207
+ },
208
+ {
209
+ title: 'Multiply',
210
+ value: MultiplyBlending,
211
+ },
212
+ {
213
+ title: 'Custom',
214
+ value: CustomBlending,
215
+ }
216
+ ];
217
+
218
+ const blendingEquationOpts: any[] = [
219
+ {
220
+ title: 'Add',
221
+ value: AddEquation,
222
+ },
223
+ {
224
+ title: 'Subtract',
225
+ value: SubtractEquation,
226
+ },
227
+ {
228
+ title: 'Reverse Subtract',
229
+ value: ReverseSubtractEquation,
230
+ },
231
+ {
232
+ title: 'Min',
233
+ value: MinEquation,
234
+ },
235
+ {
236
+ title: 'Max',
237
+ value: MaxEquation,
238
+ },
239
+ ];
240
+
241
+ // Blending Equations (Source)
242
+ const blendSourceOpts: any[] = [
243
+ {
244
+ title: 'Zero',
245
+ valye: ZeroFactor,
246
+ },
247
+ {
248
+ title: 'One',
249
+ valye: OneFactor,
250
+ },
251
+ {
252
+ title: 'Src Color',
253
+ valye: SrcColorFactor,
254
+ },
255
+ {
256
+ title: 'One Minus Src Color',
257
+ valye: OneMinusSrcColorFactor,
258
+ },
259
+ {
260
+ title: 'Src Alpha',
261
+ valye: SrcAlphaFactor,
262
+ },
263
+ {
264
+ title: 'One Minus Src Alpha',
265
+ valye: OneMinusSrcAlphaFactor,
266
+ },
267
+ {
268
+ title: 'Dst Alpha',
269
+ valye: DstAlphaFactor,
270
+ },
271
+ {
272
+ title: 'One Minus Dst Alpha',
273
+ valye: OneMinusDstAlphaFactor,
274
+ },
275
+ {
276
+ title: 'Dst Color',
277
+ valye: DstColorFactor,
278
+ },
279
+ {
280
+ title: 'One Minus Dst Color',
281
+ valye: OneMinusDstColorFactor,
282
+ },
283
+ {
284
+ title: 'Src Alpha Saturate',
285
+ valye: SrcAlphaSaturateFactor,
286
+ },
287
+ {
288
+ title: 'Constant Color',
289
+ valye: ConstantColorFactor,
290
+ },
291
+ {
292
+ title: 'One Minus Constant Color',
293
+ valye: OneMinusConstantColorFactor,
294
+ },
295
+ {
296
+ title: 'Constant Alpha',
297
+ valye: ConstantAlphaFactor,
298
+ },
299
+ {
300
+ title: 'One Minus Constant Alpha',
301
+ valye: OneMinusConstantAlphaFactor,
302
+ },
303
+ ];
304
+
305
+ // Blending Equations (Destination)
306
+ const blendDestinationOpts: any[] = [
307
+ {
308
+ title: 'Zero',
309
+ valye: ZeroFactor,
310
+ },
311
+ {
312
+ title: 'One',
313
+ valye: OneFactor,
314
+ },
315
+ {
316
+ title: 'Src Color',
317
+ valye: SrcColorFactor,
318
+ },
319
+ {
320
+ title: 'One Minus Src Color',
321
+ valye: OneMinusSrcColorFactor,
322
+ },
323
+ {
324
+ title: 'Src Alpha',
325
+ valye: SrcAlphaFactor,
326
+ },
327
+ {
328
+ title: 'One Minus Src Alpha',
329
+ valye: OneMinusSrcAlphaFactor,
330
+ },
331
+ {
332
+ title: 'Dst Alpha',
333
+ valye: DstAlphaFactor,
334
+ },
335
+ {
336
+ title: 'One Minus Dst Alpha',
337
+ valye: OneMinusDstAlphaFactor,
338
+ },
339
+ {
340
+ title: 'Dst Color',
341
+ valye: DstColorFactor,
342
+ },
343
+ {
344
+ title: 'One Minus Dst Color',
345
+ valye: OneMinusDstColorFactor,
346
+ },
347
+ {
348
+ title: 'Constant Color',
349
+ valye: ConstantColorFactor,
350
+ },
351
+ {
352
+ title: 'One Minus Constant Color',
353
+ valye: OneMinusConstantColorFactor,
354
+ },
355
+ {
356
+ title: 'Constant Alpha',
357
+ valye: ConstantAlphaFactor,
358
+ },
359
+ {
360
+ title: 'One Minus Constant Alpha',
361
+ valye: OneMinusConstantAlphaFactor,
362
+ },
363
+ ];
364
+
365
+ function updateFieldOptions(obj: any, options: any[]) {
366
+ obj.needsUpdate = true;
367
+ obj.type = 'option';
368
+ obj.options = options;
369
+ }
370
+
161
371
  export function inspectMaterialItems(material: RemoteMaterial, object: RemoteObject, three: RemoteThree): any[] {
162
372
  const items: any[] = [];
163
373
  for (const i in material) {
@@ -173,14 +383,34 @@ export function inspectMaterialItems(material: RemoteMaterial, object: RemoteObj
173
383
  value: value,
174
384
  min: undefined,
175
385
  max: undefined,
386
+ needsUpdate: propType === 'boolean',
176
387
  onChange: (prop: string, value: any) => {
177
388
  three.updateObject(object.uuid, `material.${prop}`, value);
178
- if (propType === 'boolean') three.updateObject(object.uuid, 'material.needsUpdate', true);
389
+ if (newField.needsUpdate) three.updateObject(object.uuid, 'material.needsUpdate', true);
179
390
  // Local update
180
391
  const child = three.scene?.getObjectByProperty('uuid', object.uuid);
181
392
  if (child !== undefined) setItemProps(child, `material.${prop}`, value);
182
393
  },
183
394
  };
395
+
396
+ switch (i) {
397
+ case 'blending':
398
+ updateFieldOptions(newField, blendingOpts);
399
+ break;
400
+ case 'blendDst':
401
+ updateFieldOptions(newField, blendDestinationOpts);
402
+ break;
403
+ case 'blendEquation':
404
+ updateFieldOptions(newField, blendingEquationOpts);
405
+ break;
406
+ case 'blendSrc':
407
+ updateFieldOptions(newField, blendSourceOpts);
408
+ break;
409
+ case 'side':
410
+ updateFieldOptions(newField, materialSideOpts);
411
+ break;
412
+ }
413
+
184
414
  if (clampedNames(i)) {
185
415
  newField.value = Number(value);
186
416
  // @ts-ignore
@@ -192,7 +422,33 @@ export function inspectMaterialItems(material: RemoteMaterial, object: RemoteObj
192
422
  // @ts-ignore
193
423
  newField.step = 0.01;
194
424
  }
425
+
426
+ const isShader = propType === 'string' && (i === 'vertexShader' || i === 'fragmentShader');
427
+ if (isShader) {
428
+ newField['disabled'] = false;
429
+ newField['latest'] = newField.value;
430
+ newField.onChange = (_: string, updatedValue: string) => {
431
+ newField['latest'] = updatedValue;
432
+ };
433
+ }
195
434
  items.push(newField);
435
+
436
+ if (isShader) {
437
+ items.push({
438
+ title: `${capitalize(i)} - Update`,
439
+ type: 'button',
440
+ onChange: () => {
441
+ three.updateObject(object.uuid, `material.${i}`, newField['latest']);
442
+ three.updateObject(object.uuid, 'material.needsUpdate', true);
443
+ // Local update
444
+ const child = three.scene?.getObjectByProperty('uuid', object.uuid);
445
+ if (child !== undefined) {
446
+ setItemProps(child, `material.${i}`, newField['latest']);
447
+ child['material'].needsUpdate = true;
448
+ }
449
+ },
450
+ });
451
+ }
196
452
  } else if (propType === 'object') {
197
453
  if (value.isColor) {
198
454
  items.push({
@@ -294,6 +550,7 @@ export function inspectMaterialItems(material: RemoteMaterial, object: RemoteObj
294
550
  title: vTitle,
295
551
  type: 'number',
296
552
  value: floatValue,
553
+ step: 0.01,
297
554
  onChange: (_: string, updatedValue: any) => {
298
555
  const id = `material.uniforms.${n}.value.${vProp}`;
299
556
  three.updateObject(object.uuid, id, updatedValue);
@@ -220,6 +220,26 @@ export function stripObject(obj: Object3D): RemoteObject {
220
220
  return stripped;
221
221
  }
222
222
 
223
+ export function getSubItem(child: any, key: string): any {
224
+ const keys = key.split('.');
225
+ const total = keys.length;
226
+ switch (total) {
227
+ case 1:
228
+ return child[keys[0]];
229
+ case 2:
230
+ return child[keys[0]][keys[1]];
231
+ case 3:
232
+ return child[keys[0]][keys[1]][keys[2]];
233
+ case 4:
234
+ return child[keys[0]][keys[1]][keys[2]][keys[3]];
235
+ case 5:
236
+ return child[keys[0]][keys[1]][keys[2]][keys[3]][keys[4]];
237
+ case 6:
238
+ return child[keys[0]][keys[1]][keys[2]][keys[3]][keys[4]][keys[5]];
239
+ }
240
+ return undefined;
241
+ }
242
+
223
243
  export function setItemProps(child: any, key: string, value: any) {
224
244
  const keys = key.split('.');
225
245
  const total = keys.length;
@@ -1,5 +1,9 @@
1
1
  import { Material, Mesh, Object3D, PositionalAudio, Texture } from 'three';
2
2
 
3
+ export function capitalize(value: string): string {
4
+ return value.substring(0, 1).toUpperCase() + value.substring(1);
5
+ }
6
+
3
7
  export function clamp(min: number, max: number, value: number) {
4
8
  return Math.min(max, Math.max(min, value));
5
9
  }
@@ -6,7 +6,7 @@ export default class RemoteThree extends BaseRemote {
6
6
  scene?: Scene;
7
7
  getObject(uuid: string): void;
8
8
  setObject(value: any): void;
9
- requestMethod(uuid: string, key: string, value?: any): void;
9
+ requestMethod(uuid: string, key: string, value?: any, subitem?: string): void;
10
10
  updateObject(uuid: string, key: string, value: any): void;
11
11
  createTexture(uuid: string, key: string, value: any): void;
12
12
  setScene(value: Scene): void;
@@ -1,5 +1,5 @@
1
1
  import { EventDispatcher } from 'three';
2
- export declare const debugDispatcher: EventDispatcher<import("three").Event>;
2
+ export declare const debugDispatcher: EventDispatcher<{}>;
3
3
  export declare const ToolEvents: {
4
4
  CUSTOM: string;
5
5
  SELECT_DROPDOWN: string;
@@ -1,4 +1,4 @@
1
- export type InspectorFieldType = 'string' | 'number' | 'boolean' | 'range' | 'color' | 'button' | 'image';
1
+ export type InspectorFieldType = 'string' | 'number' | 'boolean' | 'range' | 'color' | 'button' | 'image' | 'option';
2
2
  export interface InspectorFieldProps {
3
3
  title: string;
4
4
  type: InspectorFieldType;
@@ -8,6 +8,7 @@ export interface InspectorFieldProps {
8
8
  max?: number;
9
9
  step?: number;
10
10
  disabled?: boolean;
11
+ options?: any[];
11
12
  onChange?: (prop: string, value: any) => void;
12
13
  }
13
14
  export default function InspectorField(props: InspectorFieldProps): import("react/jsx-runtime").JSX.Element;
@@ -4,5 +4,6 @@ export declare function determineIcon(obj: Object3D): string;
4
4
  export declare function stripScene(obj: Object3D): MinimumObject;
5
5
  export declare function convertImageToBase64(imgElement: HTMLImageElement): string;
6
6
  export declare function stripObject(obj: Object3D): RemoteObject;
7
+ export declare function getSubItem(child: any, key: string): any;
7
8
  export declare function setItemProps(child: any, key: string, value: any): void;
8
9
  export declare function textureFromSrc(imgSource: string): Promise<Texture>;
@@ -1,4 +1,5 @@
1
1
  import { Material, Object3D, Texture } from 'three';
2
+ export declare function capitalize(value: string): string;
2
3
  export declare function clamp(min: number, max: number, value: number): number;
3
4
  export declare function distance(x: number, y: number): number;
4
5
  export declare function randomID(): string;