|
8 | 8 | MeshBuilder, |
9 | 9 | StandardMaterial, |
10 | 10 | Color3, |
11 | | - DynamicTexture |
| 11 | + Mesh |
12 | 12 | } from '@babylonjs/core' |
13 | 13 | import { Entity } from '@dcl/ecs' |
14 | 14 | import { EcsEntity } from '../EcsEntity' |
@@ -376,112 +376,111 @@ export class FreeGizmo implements IGizmoTransformer { |
376 | 376 | private createGizmoIndicator(): void { |
377 | 377 | if (this.gizmoIndicator) return |
378 | 378 |
|
379 | | - this.gizmoIndicator = MeshBuilder.CreateSphere('freeGizmoIndicator', { diameter: 0.4 }, this.scene) |
380 | | - this.gizmoIndicator.material = this.createIndicatorMaterial() |
| 379 | + this.gizmoIndicator = this.createCrossMesh() |
381 | 380 | this.gizmoIndicator.renderingGroupId = 1 |
382 | 381 | this.gizmoIndicator.alwaysSelectAsActiveMesh = true |
| 382 | + this.gizmoIndicator.doNotSyncBoundingInfo = true |
| 383 | + this.gizmoIndicator.ignoreNonUniformScaling = true |
383 | 384 | } |
384 | 385 |
|
385 | | - private createIndicatorMaterial(): StandardMaterial { |
386 | | - const material = new StandardMaterial('freeGizmoMaterial', this.scene) |
387 | | - material.diffuseTexture = this.createThreeColorTexture() |
388 | | - material.alpha = 1.0 |
389 | | - material.emissiveColor = new Color3(0.1, 0.1, 0.1) |
390 | | - return material |
391 | | - } |
392 | | - |
393 | | - private createThreeColorTexture(): DynamicTexture { |
394 | | - const textureSize = 256 |
395 | | - const dynamicTexture = new DynamicTexture('freeGizmoTexture', textureSize, this.scene) |
396 | | - const context = dynamicTexture.getContext() |
397 | | - |
398 | | - context.fillStyle = '#000000' |
399 | | - context.fillRect(0, 0, textureSize, textureSize) |
400 | | - |
401 | | - const sectionWidth = textureSize / 3 |
| 386 | + private createCrossMesh(): Mesh { |
| 387 | + const crossMesh = new Mesh('freeGizmoCross', this.utilityLayer.utilityLayerScene) |
402 | 388 |
|
403 | | - context.fillStyle = '#FF0000' |
404 | | - context.fillRect(0, 0, sectionWidth, textureSize) |
| 389 | + const leftStick = MeshBuilder.CreateBox( |
| 390 | + 'leftStick', |
| 391 | + { |
| 392 | + width: 0.25, |
| 393 | + height: 0.012, |
| 394 | + depth: 0.012 |
| 395 | + }, |
| 396 | + this.utilityLayer.utilityLayerScene |
| 397 | + ) |
| 398 | + leftStick.position.x = -0.15 |
| 399 | + leftStick.material = this.createRedMaterial() |
| 400 | + leftStick.parent = crossMesh |
| 401 | + |
| 402 | + const rightStick = MeshBuilder.CreateBox( |
| 403 | + 'rightStick', |
| 404 | + { |
| 405 | + width: 0.25, |
| 406 | + height: 0.012, |
| 407 | + depth: 0.012 |
| 408 | + }, |
| 409 | + this.utilityLayer.utilityLayerScene |
| 410 | + ) |
| 411 | + rightStick.position.x = 0.15 |
| 412 | + rightStick.material = this.createRedMaterial() |
| 413 | + rightStick.parent = crossMesh |
| 414 | + |
| 415 | + const topStick = MeshBuilder.CreateBox( |
| 416 | + 'topStick', |
| 417 | + { |
| 418 | + width: 0.012, |
| 419 | + height: 0.012, |
| 420 | + depth: 0.25 |
| 421 | + }, |
| 422 | + this.utilityLayer.utilityLayerScene |
| 423 | + ) |
| 424 | + topStick.position.z = -0.15 |
| 425 | + topStick.material = this.createBlueMaterial() |
| 426 | + topStick.parent = crossMesh |
| 427 | + |
| 428 | + const bottomStick = MeshBuilder.CreateBox( |
| 429 | + 'bottomStick', |
| 430 | + { |
| 431 | + width: 0.012, |
| 432 | + height: 0.012, |
| 433 | + depth: 0.25 |
| 434 | + }, |
| 435 | + this.utilityLayer.utilityLayerScene |
| 436 | + ) |
| 437 | + bottomStick.position.z = 0.15 |
| 438 | + bottomStick.material = this.createBlueMaterial() |
| 439 | + bottomStick.parent = crossMesh |
405 | 440 |
|
406 | | - context.fillStyle = '#00FF00' |
407 | | - context.fillRect(sectionWidth, 0, sectionWidth, textureSize) |
| 441 | + return crossMesh |
| 442 | + } |
408 | 443 |
|
409 | | - context.fillStyle = '#0000FF' |
410 | | - context.fillRect(sectionWidth * 2, 0, sectionWidth, textureSize) |
| 444 | + private createRedMaterial(): StandardMaterial { |
| 445 | + const material = new StandardMaterial('redStickMaterial', this.utilityLayer.utilityLayerScene) |
| 446 | + material.diffuseColor = new Color3(1, 0, 0) |
| 447 | + material.emissiveColor = new Color3(0.8, 0, 0) |
| 448 | + material.alpha = 1.0 |
| 449 | + material.zOffset = 2 |
| 450 | + material.forceDepthWrite = true |
| 451 | + material.disableDepthWrite = false |
| 452 | + material.backFaceCulling = false |
| 453 | + return material |
| 454 | + } |
411 | 455 |
|
412 | | - dynamicTexture.update() |
413 | | - return dynamicTexture |
| 456 | + private createBlueMaterial(): StandardMaterial { |
| 457 | + const material = new StandardMaterial('blueStickMaterial', this.utilityLayer.utilityLayerScene) |
| 458 | + material.diffuseColor = new Color3(0, 0, 1) |
| 459 | + material.emissiveColor = new Color3(0, 0, 0.8) |
| 460 | + material.alpha = 1.0 |
| 461 | + material.zOffset = 2 |
| 462 | + material.forceDepthWrite = true |
| 463 | + material.disableDepthWrite = false |
| 464 | + material.backFaceCulling = false |
| 465 | + return material |
414 | 466 | } |
415 | 467 |
|
416 | 468 | private updateGizmoIndicator(): void { |
417 | 469 | if (!this.gizmoIndicator || this.selectedEntities.length === 0) return |
418 | | - |
419 | | - const center = this.getEntityCenter() |
| 470 | + const center = this.getCentroid() |
420 | 471 | this.gizmoIndicator.position = center |
421 | 472 | } |
422 | 473 |
|
423 | | - private getEntityCenter(): Vector3 { |
424 | | - if (this.selectedEntities.length === 0) return Vector3.Zero() |
425 | | - |
426 | | - if (this.selectedEntities.length === 1) { |
427 | | - const entity = this.selectedEntities[0] |
428 | | - const boundingInfo = this.getEntityBoundingInfo(entity) |
429 | | - if (boundingInfo) { |
430 | | - return boundingInfo.boundingBox.centerWorld |
431 | | - } |
432 | | - } |
433 | | - |
434 | | - return this.calculateBoundingBoxCenter() |
435 | | - } |
436 | | - |
437 | | - private calculateBoundingBoxCenter(): Vector3 { |
438 | | - let minX = Infinity, |
439 | | - minY = Infinity, |
440 | | - minZ = Infinity |
441 | | - let maxX = -Infinity, |
442 | | - maxY = -Infinity, |
443 | | - maxZ = -Infinity |
444 | | - |
445 | | - for (const entity of this.selectedEntities) { |
446 | | - const boundingInfo = this.getEntityBoundingInfo(entity) |
447 | | - if (boundingInfo) { |
448 | | - const box = boundingInfo.boundingBox |
449 | | - minX = Math.min(minX, box.minimumWorld.x) |
450 | | - minY = Math.min(minY, box.minimumWorld.y) |
451 | | - minZ = Math.min(minZ, box.minimumWorld.z) |
452 | | - maxX = Math.max(maxX, box.maximumWorld.x) |
453 | | - maxY = Math.max(maxY, box.maximumWorld.y) |
454 | | - maxZ = Math.max(maxZ, box.maximumWorld.z) |
455 | | - } |
456 | | - } |
457 | | - |
458 | | - return new Vector3((minX + maxX) / 2, (minY + maxY) / 2, (minZ + maxZ) / 2) |
459 | | - } |
460 | | - |
461 | | - private getEntityBoundingInfo(entity: EcsEntity): any { |
462 | | - if ((entity as any).getBoundingInfo) { |
463 | | - return (entity as any).getBoundingInfo() |
464 | | - } |
465 | | - |
466 | | - if (entity.meshRenderer && (entity.meshRenderer as any).getBoundingInfo) { |
467 | | - return (entity.meshRenderer as any).getBoundingInfo() |
468 | | - } |
469 | | - |
470 | | - if (entity.gltfContainer && (entity.gltfContainer as any).getBoundingInfo) { |
471 | | - return (entity.gltfContainer as any).getBoundingInfo() |
472 | | - } |
473 | | - |
474 | | - return { |
475 | | - boundingBox: { |
476 | | - centerWorld: entity.getAbsolutePosition(), |
477 | | - minimumWorld: entity.getAbsolutePosition().subtract(new Vector3(0.5, 0.5, 0.5)), |
478 | | - maximumWorld: entity.getAbsolutePosition().add(new Vector3(0.5, 0.5, 0.5)) |
479 | | - } |
480 | | - } |
481 | | - } |
482 | | - |
483 | 474 | private removeGizmoIndicator(): void { |
484 | 475 | if (this.gizmoIndicator) { |
| 476 | + const childMeshes = this.gizmoIndicator.getChildMeshes() |
| 477 | + childMeshes.forEach((child) => { |
| 478 | + if (child.material) { |
| 479 | + child.material.dispose() |
| 480 | + } |
| 481 | + child.dispose() |
| 482 | + }) |
| 483 | + |
485 | 484 | this.gizmoIndicator.dispose() |
486 | 485 | this.gizmoIndicator = null |
487 | 486 | } |
|
0 commit comments