From 78fdd3a17ffee53eaf718c632999b7e8a9a8edc4 Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 28 Jan 2025 17:04:28 +0100 Subject: [PATCH 01/16] Introduction for supporting 3D cube base color --- Extensions/3D/Cube3DRuntimeObject.ts | 19 ++++- .../3D/Cube3DRuntimeObjectPixiRenderer.ts | 82 ++++++++++++------- Extensions/3D/JsExtension.js | 70 ++++++++-------- 3 files changed, 106 insertions(+), 65 deletions(-) diff --git a/Extensions/3D/Cube3DRuntimeObject.ts b/Extensions/3D/Cube3DRuntimeObject.ts index b61d05e09dd9..c0b1e950b3c0 100644 --- a/Extensions/3D/Cube3DRuntimeObject.ts +++ b/Extensions/3D/Cube3DRuntimeObject.ts @@ -24,10 +24,10 @@ namespace gdjs { rightFaceVisible: boolean; topFaceVisible: boolean; bottomFaceVisible: boolean; + color: THREE.Color; materialType: 'Basic' | 'StandardWithoutMetalness'; }; } - type FaceName = 'front' | 'back' | 'left' | 'right' | 'top' | 'bottom'; const faceNameToBitmaskIndex = { front: 0, @@ -71,7 +71,7 @@ namespace gdjs { ]; _materialType: gdjs.Cube3DRuntimeObject.MaterialType = gdjs.Cube3DRuntimeObject.MaterialType.Basic; - + _color: THREE.Color; constructor( instanceContainer: gdjs.RuntimeInstanceContainer, objectData: Cube3DObjectData @@ -117,6 +117,9 @@ namespace gdjs { objectData.content.topFaceResourceName, objectData.content.bottomFaceResourceName, ]; + + this._color = objectData.content.color || new THREE.Color(0.5, 0.5, 0.5); + this._materialType = this._convertMaterialType( objectData.content.materialType ); @@ -197,16 +200,20 @@ namespace gdjs { setFaceResourceName(faceName: FaceName, resourceName: string): void { const faceIndex = faceNameToBitmaskIndex[faceName]; + console.log(resourceName); if (faceIndex === undefined) { return; } if (this._faceResourceNames[faceIndex] === resourceName) { return; } - this._faceResourceNames[faceIndex] = resourceName; this._renderer.updateFace(faceIndex); } + setCubeColor(color: THREE.Color): void { + if (color === this._color) return; + this._color = color; + } /** @internal */ getFaceAtIndexResourceName(faceIndex: integer): string { @@ -285,7 +292,11 @@ namespace gdjs { if ( oldObjectData.content.frontFaceResourceName !== newObjectData.content.frontFaceResourceName - ) { + ) + if (oldObjectData.content.color !== newObjectData.content.color) { + this.setCubeColor(newObjectData.content.color); + } + { this.setFaceResourceName( 'front', newObjectData.content.frontFaceResourceName diff --git a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts index 73b9e6f1181b..9598b24df5c4 100644 --- a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts +++ b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts @@ -53,6 +53,12 @@ namespace gdjs { if (!runtimeObject.isFaceAtIndexVisible(faceIndex)) return getTransparentMaterial(); + const resourceName = runtimeObject.getFaceAtIndexResourceName(faceIndex); + if (!resourceName || resourceName === '') { + const material = new THREE.MeshBasicMaterial({ vertexColors: true }); + console.log('on est bien passés ici !!'); + return material; + } return runtimeObject .getInstanceContainer() .getGame() @@ -75,14 +81,37 @@ namespace gdjs { ) { const geometry = new THREE.BoxGeometry(1, 1, 1); // TODO (3D) - feature: support color instead of texture? - const materials = [ - getFaceMaterial(runtimeObject, materialIndexToFaceIndex[0]), - getFaceMaterial(runtimeObject, materialIndexToFaceIndex[1]), - getFaceMaterial(runtimeObject, materialIndexToFaceIndex[2]), - getFaceMaterial(runtimeObject, materialIndexToFaceIndex[3]), - getFaceMaterial(runtimeObject, materialIndexToFaceIndex[4]), - getFaceMaterial(runtimeObject, materialIndexToFaceIndex[5]), - ]; + const materials: THREE.Material[] = []; + + for (let i = 0; i < 6; i++) { + const material: THREE.Material = getFaceMaterial( + runtimeObject, + materialIndexToFaceIndex[i] + ); + const basicMaterial: THREE.MeshBasicMaterial = + new THREE.MeshBasicMaterial(); + basicMaterial.copy(material); + materials.push( + basicMaterial.map + ? getFaceMaterial(runtimeObject, materialIndexToFaceIndex[i]) + : new THREE.MeshBasicMaterial({ vertexColors: true }) + ); + } + + let colors: number[] = []; + for (let i = 0; i < geometry.attributes.position.count; i++) { + colors.push( + runtimeObject._color.r, + runtimeObject._color.g, + runtimeObject._color.b + ); + } + + geometry.setAttribute( + 'color', + new THREE.BufferAttribute(new Float32Array(colors), 3) + ); + const boxMesh = new THREE.Mesh(geometry, materials); super(runtimeObject, instanceContainer, boxMesh); @@ -121,13 +150,11 @@ namespace gdjs { */ updateTextureUvMapping(faceIndex?: number) { // @ts-ignore - position is stored as a Float32BufferAttribute - const pos: THREE.BufferAttribute = this._boxMesh.geometry.getAttribute( - 'position' - ); + const pos: THREE.BufferAttribute = + this._boxMesh.geometry.getAttribute('position'); // @ts-ignore - uv is stored as a Float32BufferAttribute - const uvMapping: THREE.BufferAttribute = this._boxMesh.geometry.getAttribute( - 'uv' - ); + const uvMapping: THREE.BufferAttribute = + this._boxMesh.geometry.getAttribute('uv'); const startIndex = faceIndex === undefined ? 0 : faceIndexToMaterialIndex[faceIndex] * 4; const endIndex = @@ -149,9 +176,10 @@ namespace gdjs { continue; } - const shouldRepeatTexture = this._cube3DRuntimeObject.shouldRepeatTextureOnFaceAtIndex( - materialIndexToFaceIndex[materialIndex] - ); + const shouldRepeatTexture = + this._cube3DRuntimeObject.shouldRepeatTextureOnFaceAtIndex( + materialIndexToFaceIndex[materialIndex] + ); const shouldOrientateFacesTowardsY = this._cube3DRuntimeObject.getFacesOrientation() === 'Y'; @@ -180,12 +208,10 @@ namespace gdjs { if (shouldOrientateFacesTowardsY) { [x, y] = noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4]; } else { - [ - x, - y, - ] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ - vertexIndex % 4 - ]; + [x, y] = + noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ + vertexIndex % 4 + ]; } } break; @@ -211,12 +237,10 @@ namespace gdjs { if (shouldOrientateFacesTowardsY) { [x, y] = noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4]; } else { - [ - x, - y, - ] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ - vertexIndex % 4 - ]; + [x, y] = + noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ + vertexIndex % 4 + ]; x = -x; y = -y; } diff --git a/Extensions/3D/JsExtension.js b/Extensions/3D/JsExtension.js index 0216ed7a4f47..071bbf156fdb 100644 --- a/Extensions/3D/JsExtension.js +++ b/Extensions/3D/JsExtension.js @@ -822,7 +822,8 @@ module.exports = { propertyName === 'bottomFaceResourceName' || propertyName === 'backFaceUpThroughWhichAxisRotation' || propertyName === 'facesOrientation' || - propertyName === 'materialType' + propertyName === 'materialType' || + propertyName === 'cubeColor' ) { objectContent[propertyName] = newValue; return true; @@ -902,6 +903,12 @@ module.exports = { .setLabel(_('Depth')) .setMeasurementUnit(gd.MeasurementUnit.getPixel()) .setGroup(_('Default size')); + objectProperties + .getOrCreate('cubeColor') + .setValue(objectContent.color || (255, 255, 255)) + .setType('Color') + .setLabel(_('Cube color')) + .setGroup(_('Texture')); objectProperties .getOrCreate('frontFaceResourceName') @@ -2160,9 +2167,10 @@ module.exports = { } static getThumbnail(project, resourcesLoader, objectConfiguration) { - const textureResourceName = RenderedCube3DObject2DInstance._getResourceNameToDisplay( - objectConfiguration - ); + const textureResourceName = + RenderedCube3DObject2DInstance._getResourceNameToDisplay( + objectConfiguration + ); if (textureResourceName) { return resourcesLoader.getResourceFullUrl( project, @@ -2174,18 +2182,20 @@ module.exports = { } updateTextureIfNeeded() { - const textureName = RenderedCube3DObject2DInstance._getResourceNameToDisplay( - this._associatedObjectConfiguration - ); + const textureName = + RenderedCube3DObject2DInstance._getResourceNameToDisplay( + this._associatedObjectConfiguration + ); if (textureName === this._renderedResourceName) return; this.updateTexture(); } updateTexture() { - const textureName = RenderedCube3DObject2DInstance._getResourceNameToDisplay( - this._associatedObjectConfiguration - ); + const textureName = + RenderedCube3DObject2DInstance._getResourceNameToDisplay( + this._associatedObjectConfiguration + ); if (!textureName) { this._renderFallbackObject = true; @@ -2496,7 +2506,8 @@ module.exports = { backFaceUpThroughWhichAxisRotation !== this._backFaceUpThroughWhichAxisRotation ) { - this._backFaceUpThroughWhichAxisRotation = backFaceUpThroughWhichAxisRotation; + this._backFaceUpThroughWhichAxisRotation = + backFaceUpThroughWhichAxisRotation; uvMappingDirty = true; } @@ -2552,9 +2563,10 @@ module.exports = { continue; } - const shouldRepeatTexture = this._shouldRepeatTextureOnFace[ - materialIndexToFaceIndex[materialIndex] - ]; + const shouldRepeatTexture = + this._shouldRepeatTextureOnFace[ + materialIndexToFaceIndex[materialIndex] + ]; const shouldOrientateFacesTowardsY = this._facesOrientation === 'Y'; @@ -2589,16 +2601,13 @@ module.exports = { } } else { if (shouldOrientateFacesTowardsY) { - [x, y] = noRepeatTextureVertexIndexToUvMapping[ - vertexIndex % 4 - ]; + [x, y] = + noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4]; } else { - [ - x, - y, - ] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ - vertexIndex % 4 - ]; + [x, y] = + noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ + vertexIndex % 4 + ]; } } break; @@ -2628,16 +2637,13 @@ module.exports = { } } else { if (shouldOrientateFacesTowardsY) { - [x, y] = noRepeatTextureVertexIndexToUvMapping[ - vertexIndex % 4 - ]; + [x, y] = + noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4]; } else { - [ - x, - y, - ] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ - vertexIndex % 4 - ]; + [x, y] = + noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ + vertexIndex % 4 + ]; x = -x; y = -y; } From 63c8ff046e2008fbb91785f2fe296b8ef5494b8b Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 28 Jan 2025 17:11:29 +0100 Subject: [PATCH 02/16] removed console.log --- Extensions/3D/Cube3DRuntimeObject.ts | 1 - Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/Extensions/3D/Cube3DRuntimeObject.ts b/Extensions/3D/Cube3DRuntimeObject.ts index c0b1e950b3c0..083b92fcfa7e 100644 --- a/Extensions/3D/Cube3DRuntimeObject.ts +++ b/Extensions/3D/Cube3DRuntimeObject.ts @@ -200,7 +200,6 @@ namespace gdjs { setFaceResourceName(faceName: FaceName, resourceName: string): void { const faceIndex = faceNameToBitmaskIndex[faceName]; - console.log(resourceName); if (faceIndex === undefined) { return; } diff --git a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts index 9598b24df5c4..12ed37a12e94 100644 --- a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts +++ b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts @@ -56,7 +56,6 @@ namespace gdjs { const resourceName = runtimeObject.getFaceAtIndexResourceName(faceIndex); if (!resourceName || resourceName === '') { const material = new THREE.MeshBasicMaterial({ vertexColors: true }); - console.log('on est bien passés ici !!'); return material; } return runtimeObject From 0c3b5108625256758fb0dd0e155db8ede5cedab2 Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 28 Jan 2025 17:36:00 +0100 Subject: [PATCH 03/16] formatting --- .../3D/Cube3DRuntimeObjectPixiRenderer.ts | 40 ++++++------ Extensions/3D/JsExtension.js | 61 ++++++++++--------- 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts index 12ed37a12e94..5fd34f98c97f 100644 --- a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts +++ b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts @@ -87,8 +87,7 @@ namespace gdjs { runtimeObject, materialIndexToFaceIndex[i] ); - const basicMaterial: THREE.MeshBasicMaterial = - new THREE.MeshBasicMaterial(); + const basicMaterial: THREE.MeshBasicMaterial = new THREE.MeshBasicMaterial(); basicMaterial.copy(material); materials.push( basicMaterial.map @@ -149,11 +148,13 @@ namespace gdjs { */ updateTextureUvMapping(faceIndex?: number) { // @ts-ignore - position is stored as a Float32BufferAttribute - const pos: THREE.BufferAttribute = - this._boxMesh.geometry.getAttribute('position'); + const pos: THREE.BufferAttribute = this._boxMesh.geometry.getAttribute( + 'position' + ); // @ts-ignore - uv is stored as a Float32BufferAttribute - const uvMapping: THREE.BufferAttribute = - this._boxMesh.geometry.getAttribute('uv'); + const uvMapping: THREE.BufferAttribute = this._boxMesh.geometry.getAttribute( + 'uv' + ); const startIndex = faceIndex === undefined ? 0 : faceIndexToMaterialIndex[faceIndex] * 4; const endIndex = @@ -175,10 +176,9 @@ namespace gdjs { continue; } - const shouldRepeatTexture = - this._cube3DRuntimeObject.shouldRepeatTextureOnFaceAtIndex( - materialIndexToFaceIndex[materialIndex] - ); + const shouldRepeatTexture = this._cube3DRuntimeObject.shouldRepeatTextureOnFaceAtIndex( + materialIndexToFaceIndex[materialIndex] + ); const shouldOrientateFacesTowardsY = this._cube3DRuntimeObject.getFacesOrientation() === 'Y'; @@ -207,10 +207,12 @@ namespace gdjs { if (shouldOrientateFacesTowardsY) { [x, y] = noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4]; } else { - [x, y] = - noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ - vertexIndex % 4 - ]; + [ + x, + y, + ] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ + vertexIndex % 4 + ]; } } break; @@ -236,10 +238,12 @@ namespace gdjs { if (shouldOrientateFacesTowardsY) { [x, y] = noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4]; } else { - [x, y] = - noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ - vertexIndex % 4 - ]; + [ + x, + y, + ] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ + vertexIndex % 4 + ]; x = -x; y = -y; } diff --git a/Extensions/3D/JsExtension.js b/Extensions/3D/JsExtension.js index 071bbf156fdb..a77285b35e8f 100644 --- a/Extensions/3D/JsExtension.js +++ b/Extensions/3D/JsExtension.js @@ -2167,10 +2167,9 @@ module.exports = { } static getThumbnail(project, resourcesLoader, objectConfiguration) { - const textureResourceName = - RenderedCube3DObject2DInstance._getResourceNameToDisplay( - objectConfiguration - ); + const textureResourceName = RenderedCube3DObject2DInstance._getResourceNameToDisplay( + objectConfiguration + ); if (textureResourceName) { return resourcesLoader.getResourceFullUrl( project, @@ -2182,20 +2181,18 @@ module.exports = { } updateTextureIfNeeded() { - const textureName = - RenderedCube3DObject2DInstance._getResourceNameToDisplay( - this._associatedObjectConfiguration - ); + const textureName = RenderedCube3DObject2DInstance._getResourceNameToDisplay( + this._associatedObjectConfiguration + ); if (textureName === this._renderedResourceName) return; this.updateTexture(); } updateTexture() { - const textureName = - RenderedCube3DObject2DInstance._getResourceNameToDisplay( - this._associatedObjectConfiguration - ); + const textureName = RenderedCube3DObject2DInstance._getResourceNameToDisplay( + this._associatedObjectConfiguration + ); if (!textureName) { this._renderFallbackObject = true; @@ -2506,8 +2503,7 @@ module.exports = { backFaceUpThroughWhichAxisRotation !== this._backFaceUpThroughWhichAxisRotation ) { - this._backFaceUpThroughWhichAxisRotation = - backFaceUpThroughWhichAxisRotation; + this._backFaceUpThroughWhichAxisRotation = backFaceUpThroughWhichAxisRotation; uvMappingDirty = true; } @@ -2563,10 +2559,9 @@ module.exports = { continue; } - const shouldRepeatTexture = - this._shouldRepeatTextureOnFace[ - materialIndexToFaceIndex[materialIndex] - ]; + const shouldRepeatTexture = this._shouldRepeatTextureOnFace[ + materialIndexToFaceIndex[materialIndex] + ]; const shouldOrientateFacesTowardsY = this._facesOrientation === 'Y'; @@ -2601,13 +2596,16 @@ module.exports = { } } else { if (shouldOrientateFacesTowardsY) { - [x, y] = - noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4]; + [x, y] = noRepeatTextureVertexIndexToUvMapping[ + vertexIndex % 4 + ]; } else { - [x, y] = - noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ - vertexIndex % 4 - ]; + [ + x, + y, + ] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ + vertexIndex % 4 + ]; } } break; @@ -2637,13 +2635,16 @@ module.exports = { } } else { if (shouldOrientateFacesTowardsY) { - [x, y] = - noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4]; + [x, y] = noRepeatTextureVertexIndexToUvMapping[ + vertexIndex % 4 + ]; } else { - [x, y] = - noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ - vertexIndex % 4 - ]; + [ + x, + y, + ] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[ + vertexIndex % 4 + ]; x = -x; y = -y; } From e69d65909a79393af6dc8301296cc1e5e6a7b9bc Mon Sep 17 00:00:00 2001 From: Neyl Date: Wed, 29 Jan 2025 11:50:30 +0100 Subject: [PATCH 04/16] fixed format for color propertie --- Extensions/3D/Cube3DRuntimeObject.ts | 14 ++++++++------ Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts | 6 +++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Extensions/3D/Cube3DRuntimeObject.ts b/Extensions/3D/Cube3DRuntimeObject.ts index 083b92fcfa7e..30036ca76001 100644 --- a/Extensions/3D/Cube3DRuntimeObject.ts +++ b/Extensions/3D/Cube3DRuntimeObject.ts @@ -24,7 +24,7 @@ namespace gdjs { rightFaceVisible: boolean; topFaceVisible: boolean; bottomFaceVisible: boolean; - color: THREE.Color; + color: string; materialType: 'Basic' | 'StandardWithoutMetalness'; }; } @@ -71,7 +71,7 @@ namespace gdjs { ]; _materialType: gdjs.Cube3DRuntimeObject.MaterialType = gdjs.Cube3DRuntimeObject.MaterialType.Basic; - _color: THREE.Color; + _color: [float, float, float]; constructor( instanceContainer: gdjs.RuntimeInstanceContainer, objectData: Cube3DObjectData @@ -118,7 +118,9 @@ namespace gdjs { objectData.content.bottomFaceResourceName, ]; - this._color = objectData.content.color || new THREE.Color(0.5, 0.5, 0.5); + this._color = objectData.content.color + ? rgbOrHexToRGBColor(objectData.content.color) + : [0.5, 0.5, 0.5]; this._materialType = this._convertMaterialType( objectData.content.materialType @@ -209,9 +211,9 @@ namespace gdjs { this._faceResourceNames[faceIndex] = resourceName; this._renderer.updateFace(faceIndex); } - setCubeColor(color: THREE.Color): void { - if (color === this._color) return; - this._color = color; + setCubeColor(color: string): void { + if (rgbOrHexToRGBColor(color) === this._color) return; + this._color = rgbOrHexToRGBColor(color); } /** @internal */ diff --git a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts index 5fd34f98c97f..ee0b3f968951 100644 --- a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts +++ b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts @@ -99,9 +99,9 @@ namespace gdjs { let colors: number[] = []; for (let i = 0; i < geometry.attributes.position.count; i++) { colors.push( - runtimeObject._color.r, - runtimeObject._color.g, - runtimeObject._color.b + runtimeObject._color[0], + runtimeObject._color[1], + runtimeObject._color[2] ); } From de558b00df2624233b623fc7a1f5f520868f15a7 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 3 Feb 2025 10:15:57 +0100 Subject: [PATCH 05/16] support for cube color in preview mode, base for editor render --- Extensions/3D/Cube3DRuntimeObject.ts | 22 ++++---- .../3D/Cube3DRuntimeObjectPixiRenderer.ts | 56 +++++++++---------- Extensions/3D/JsExtension.js | 42 +++++++++++--- 3 files changed, 74 insertions(+), 46 deletions(-) diff --git a/Extensions/3D/Cube3DRuntimeObject.ts b/Extensions/3D/Cube3DRuntimeObject.ts index 30036ca76001..beedb16de553 100644 --- a/Extensions/3D/Cube3DRuntimeObject.ts +++ b/Extensions/3D/Cube3DRuntimeObject.ts @@ -71,7 +71,7 @@ namespace gdjs { ]; _materialType: gdjs.Cube3DRuntimeObject.MaterialType = gdjs.Cube3DRuntimeObject.MaterialType.Basic; - _color: [float, float, float]; + _color: number; constructor( instanceContainer: gdjs.RuntimeInstanceContainer, objectData: Cube3DObjectData @@ -119,8 +119,8 @@ namespace gdjs { ]; this._color = objectData.content.color - ? rgbOrHexToRGBColor(objectData.content.color) - : [0.5, 0.5, 0.5]; + ? gdjs.rgbOrHexStringToNumber(objectData.content.color) + : gdjs.rgbOrHexStringToNumber('#808080'); this._materialType = this._convertMaterialType( objectData.content.materialType @@ -212,8 +212,10 @@ namespace gdjs { this._renderer.updateFace(faceIndex); } setCubeColor(color: string): void { - if (rgbOrHexToRGBColor(color) === this._color) return; - this._color = rgbOrHexToRGBColor(color); + let colorinHex = gdjs.rgbOrHexStringToNumber(color); + if (colorinHex === this._color) return; + this._color = colorinHex; + this._renderer.updateColor(); } /** @internal */ @@ -293,16 +295,16 @@ namespace gdjs { if ( oldObjectData.content.frontFaceResourceName !== newObjectData.content.frontFaceResourceName - ) - if (oldObjectData.content.color !== newObjectData.content.color) { - this.setCubeColor(newObjectData.content.color); - } - { + ) { this.setFaceResourceName( 'front', newObjectData.content.frontFaceResourceName ); } + if (oldObjectData.content.color !== newObjectData.content.color) { + this.setCubeColor(newObjectData.content.color); + } + if ( oldObjectData.content.backFaceResourceName !== newObjectData.content.backFaceResourceName diff --git a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts index ee0b3f968951..ee5a9b5ce516 100644 --- a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts +++ b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts @@ -79,36 +79,16 @@ namespace gdjs { instanceContainer: gdjs.RuntimeInstanceContainer ) { const geometry = new THREE.BoxGeometry(1, 1, 1); - // TODO (3D) - feature: support color instead of texture? - const materials: THREE.Material[] = []; - for (let i = 0; i < 6; i++) { - const material: THREE.Material = getFaceMaterial( - runtimeObject, - materialIndexToFaceIndex[i] - ); - const basicMaterial: THREE.MeshBasicMaterial = new THREE.MeshBasicMaterial(); - basicMaterial.copy(material); - materials.push( - basicMaterial.map - ? getFaceMaterial(runtimeObject, materialIndexToFaceIndex[i]) - : new THREE.MeshBasicMaterial({ vertexColors: true }) - ); - } - - let colors: number[] = []; - for (let i = 0; i < geometry.attributes.position.count; i++) { - colors.push( - runtimeObject._color[0], - runtimeObject._color[1], - runtimeObject._color[2] - ); - } - - geometry.setAttribute( - 'color', - new THREE.BufferAttribute(new Float32Array(colors), 3) - ); + const materials: THREE.Material[] = new Array(6) + .fill(0) + .map((_, index) => { + const material: THREE.Material = getFaceMaterial( + runtimeObject, + materialIndexToFaceIndex[index] + ); + return material; + }); const boxMesh = new THREE.Mesh(geometry, materials); @@ -119,6 +99,24 @@ namespace gdjs { this.updateSize(); this.updatePosition(); this.updateRotation(); + this.updateColor(); + } + updateColor() { + let colors: number[] = []; + + let color = gdjs.hexNumberToRGBArray(this._cube3DRuntimeObject._color); + for ( + let i = 0; + i < this._boxMesh.geometry.attributes.position.count; + i++ + ) { + colors.push(color[0] / 255, color[1] / 255, color[2] / 255); + } + + this._boxMesh.geometry.setAttribute( + 'color', + new THREE.BufferAttribute(new Float32Array(colors), 3) + ); } updateFace(faceIndex: integer) { diff --git a/Extensions/3D/JsExtension.js b/Extensions/3D/JsExtension.js index a77285b35e8f..13e99d94b911 100644 --- a/Extensions/3D/JsExtension.js +++ b/Extensions/3D/JsExtension.js @@ -823,7 +823,7 @@ module.exports = { propertyName === 'backFaceUpThroughWhichAxisRotation' || propertyName === 'facesOrientation' || propertyName === 'materialType' || - propertyName === 'cubeColor' + propertyName === 'color' ) { objectContent[propertyName] = newValue; return true; @@ -904,10 +904,10 @@ module.exports = { .setMeasurementUnit(gd.MeasurementUnit.getPixel()) .setGroup(_('Default size')); objectProperties - .getOrCreate('cubeColor') - .setValue(objectContent.color || (255, 255, 255)) + .getOrCreate('color') + .setValue(objectContent.color || '128;128;128') .setType('Color') - .setLabel(_('Cube color')) + .setLabel(_('Color')) .setGroup(_('Texture')); objectProperties @@ -2364,17 +2364,26 @@ module.exports = { async _updateThreeObjectMaterials() { const getFaceMaterial = async (project, faceIndex) => { - if (!this._faceVisibilities[faceIndex]) + if (!this._faceVisibilities[faceIndex]) { return getTransparentMaterial(); - + } + + const resourceName = this._faceResourceNames[faceIndex]; + + if (!resourceName || resourceName === '') { + return new THREE.MeshBasicMaterial({ vertexColors: true }); + } + + // Utilisation du loader de ressources pour obtenir le matériau return await this._pixiResourcesLoader.getThreeMaterial( project, - this._faceResourceNames[faceIndex], + resourceName, { useTransparentTexture: this._shouldUseTransparentTexture, } ); }; + const materials = await Promise.all([ getFaceMaterial(this._project, materialIndexToFaceIndex[0]), @@ -2394,6 +2403,25 @@ module.exports = { this._threeObject.material[5] = materials[5]; this._updateTextureUvMapping(); + this.updateColor(); + } + + updateColor() { + let colors: number[] = []; + + let color = gdjs.hexNumberToRGBArray(this._cube3DRuntimeObject._color); + for ( + let i = 0; + i < this._boxMesh.geometry.attributes.position.count; + i++ + ) { + colors.push(color[0] / 255, color[1] / 255, color[2] / 255); + } + + this._boxMesh.geometry.setAttribute( + 'color', + new THREE.BufferAttribute(new Float32Array(colors), 3) + ); } static _getResourceNameToDisplay(objectConfiguration) { From 0400b0f7693fdb69e41a76dbbf077da066ad00be Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 3 Feb 2025 10:16:58 +0100 Subject: [PATCH 06/16] format --- Extensions/3D/JsExtension.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Extensions/3D/JsExtension.js b/Extensions/3D/JsExtension.js index 13e99d94b911..fb8ea95543f6 100644 --- a/Extensions/3D/JsExtension.js +++ b/Extensions/3D/JsExtension.js @@ -2367,13 +2367,13 @@ module.exports = { if (!this._faceVisibilities[faceIndex]) { return getTransparentMaterial(); } - + const resourceName = this._faceResourceNames[faceIndex]; - + if (!resourceName || resourceName === '') { return new THREE.MeshBasicMaterial({ vertexColors: true }); } - + // Utilisation du loader de ressources pour obtenir le matériau return await this._pixiResourcesLoader.getThreeMaterial( project, @@ -2383,7 +2383,6 @@ module.exports = { } ); }; - const materials = await Promise.all([ getFaceMaterial(this._project, materialIndexToFaceIndex[0]), @@ -2408,7 +2407,7 @@ module.exports = { updateColor() { let colors: number[] = []; - + let color = gdjs.hexNumberToRGBArray(this._cube3DRuntimeObject._color); for ( let i = 0; @@ -2417,7 +2416,7 @@ module.exports = { ) { colors.push(color[0] / 255, color[1] / 255, color[2] / 255); } - + this._boxMesh.geometry.setAttribute( 'color', new THREE.BufferAttribute(new Float32Array(colors), 3) From 9af6a4244d66a2ea37ce337de56e5f47fb916427 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 3 Feb 2025 17:43:33 +0100 Subject: [PATCH 07/16] attempt at fixing editor rendering for cube base color --- Extensions/3D/JsExtension.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Extensions/3D/JsExtension.js b/Extensions/3D/JsExtension.js index fb8ea95543f6..f404a0f0d579 100644 --- a/Extensions/3D/JsExtension.js +++ b/Extensions/3D/JsExtension.js @@ -1099,6 +1099,7 @@ module.exports = { topFaceResourceRepeat: false, bottomFaceResourceRepeat: false, materialType: 'Basic', + color: '128;128;128', }; Cube3DObject.updateInitialInstanceProperty = function ( @@ -2402,22 +2403,26 @@ module.exports = { this._threeObject.material[5] = materials[5]; this._updateTextureUvMapping(); - this.updateColor(); } - updateColor() { + updateColor(object) { let colors: number[] = []; - let color = gdjs.hexNumberToRGBArray(this._cube3DRuntimeObject._color); + let color; + if (object.content.color) { + color = gdjs.hexNumberToRGBArray(object.content.color); + } else { + color = '128;128;128'; + } for ( let i = 0; - i < this._boxMesh.geometry.attributes.position.count; + i < this._threeObject.geometry.attributes.position.count; i++ ) { colors.push(color[0] / 255, color[1] / 255, color[2] / 255); } - this._boxMesh.geometry.setAttribute( + this._threeObject.geometry.setAttribute( 'color', new THREE.BufferAttribute(new Float32Array(colors), 3) ); @@ -2554,6 +2559,7 @@ module.exports = { if (materialsDirty) this._updateThreeObjectMaterials(); if (uvMappingDirty) this._updateTextureUvMapping(); + this.updateColor(object.content); } /** From 3f3a4c332f60b81c27eecf720cc43401c089ec14 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 3 Feb 2025 19:18:17 +0100 Subject: [PATCH 08/16] Cube color in the editor renderer is now supported --- Extensions/3D/JsExtension.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Extensions/3D/JsExtension.js b/Extensions/3D/JsExtension.js index f404a0f0d579..0688369b08b7 100644 --- a/Extensions/3D/JsExtension.js +++ b/Extensions/3D/JsExtension.js @@ -2406,14 +2406,15 @@ module.exports = { } updateColor(object) { - let colors: number[] = []; + let colors = []; let color; if (object.content.color) { - color = gdjs.hexNumberToRGBArray(object.content.color); + color = object.content.color.split(';').map(Number); } else { - color = '128;128;128'; + color = [128, 128, 128]; } + for ( let i = 0; i < this._threeObject.geometry.attributes.position.count; @@ -2559,7 +2560,7 @@ module.exports = { if (materialsDirty) this._updateThreeObjectMaterials(); if (uvMappingDirty) this._updateTextureUvMapping(); - this.updateColor(object.content); + this.updateColor(object); } /** From 4117f53b674157a88c7b00fee1a42c1e36752872 Mon Sep 17 00:00:00 2001 From: Neyl Date: Wed, 5 Feb 2025 16:04:59 +0100 Subject: [PATCH 09/16] added an action to change the color of a cube --- Extensions/3D/Cube3DRuntimeObject.ts | 12 ++++++++++-- Extensions/3D/JsExtension.js | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Extensions/3D/Cube3DRuntimeObject.ts b/Extensions/3D/Cube3DRuntimeObject.ts index beedb16de553..96626fc7b4c5 100644 --- a/Extensions/3D/Cube3DRuntimeObject.ts +++ b/Extensions/3D/Cube3DRuntimeObject.ts @@ -45,6 +45,7 @@ namespace gdjs { trfb: integer; frn: [string, string, string, string, string, string]; mt: number; + c: number; }; type Cube3DObjectNetworkSyncData = Object3DNetworkSyncData & @@ -211,7 +212,7 @@ namespace gdjs { this._faceResourceNames[faceIndex] = resourceName; this._renderer.updateFace(faceIndex); } - setCubeColor(color: string): void { + setColor(color: string): void { let colorinHex = gdjs.rgbOrHexStringToNumber(color); if (colorinHex === this._color) return; this._color = colorinHex; @@ -302,7 +303,7 @@ namespace gdjs { ); } if (oldObjectData.content.color !== newObjectData.content.color) { - this.setCubeColor(newObjectData.content.color); + this.setColor(newObjectData.content.color); } if ( @@ -437,6 +438,7 @@ namespace gdjs { vfb: this._visibleFacesBitmask, trfb: this._textureRepeatFacesBitmask, frn: this._faceResourceNames, + c: this._color, }; } @@ -490,6 +492,12 @@ namespace gdjs { } } } + if (networkSyncData.c !== undefined) { + if (this._color !== networkSyncData.c) { + this._color = networkSyncData.c; + this._renderer.updateColor(); + } + } } /** diff --git a/Extensions/3D/JsExtension.js b/Extensions/3D/JsExtension.js index 0688369b08b7..7a436b04aafe 100644 --- a/Extensions/3D/JsExtension.js +++ b/Extensions/3D/JsExtension.js @@ -1576,6 +1576,21 @@ module.exports = { .addParameter('imageResource', _('Image'), '', false) .setFunctionName('setFaceResourceName'); + object + .addScopedAction( + 'SetColor', + _('Color'), + _('Change the color of the cube.'), + _('Change the color of _PARAM0_ to _PARAM1_'), + _('Color'), + 'res/actions/color24.png', + 'res/actions/color.png' + ) + .addParameter('object', _('3D Cube'), 'Cube3DObject', false) + .addParameter('color', _('Color'), '', false) + .getCodeExtraInformation() + .setFunctionName('setColor'); + extension .addExpressionAndConditionAndAction( 'number', From 1a2193d3142631cf3dc2addb0fa5ceb879f2f294 Mon Sep 17 00:00:00 2001 From: Neyl Date: Wed, 5 Feb 2025 17:08:29 +0100 Subject: [PATCH 10/16] updated color updating, added helper function from gdjs to objectrenderingservice --- Extensions/3D/Cube3DRuntimeObject.ts | 8 +++---- .../3D/Cube3DRuntimeObjectPixiRenderer.ts | 24 +++++++++---------- Extensions/3D/JsExtension.js | 24 +++++++++++-------- Extensions/JsExtensionTypes.d.ts | 1 + .../ObjectsRenderingService.js | 7 +++++- newIDE/app/src/Utils/ColorTransformer.js | 10 ++++++++ 6 files changed, 46 insertions(+), 28 deletions(-) diff --git a/Extensions/3D/Cube3DRuntimeObject.ts b/Extensions/3D/Cube3DRuntimeObject.ts index 96626fc7b4c5..2c7c859c534b 100644 --- a/Extensions/3D/Cube3DRuntimeObject.ts +++ b/Extensions/3D/Cube3DRuntimeObject.ts @@ -119,9 +119,9 @@ namespace gdjs { objectData.content.bottomFaceResourceName, ]; - this._color = objectData.content.color - ? gdjs.rgbOrHexStringToNumber(objectData.content.color) - : gdjs.rgbOrHexStringToNumber('#808080'); + this._color = gdjs.rgbOrHexStringToNumber( + objectData.content.color || '128;128;128' + ); this._materialType = this._convertMaterialType( objectData.content.materialType @@ -213,7 +213,7 @@ namespace gdjs { this._renderer.updateFace(faceIndex); } setColor(color: string): void { - let colorinHex = gdjs.rgbOrHexStringToNumber(color); + const colorinHex = gdjs.rgbOrHexStringToNumber(color); if (colorinHex === this._color) return; this._color = colorinHex; this._renderer.updateColor(); diff --git a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts index ee5a9b5ce516..eb92de06e2b0 100644 --- a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts +++ b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts @@ -54,9 +54,8 @@ namespace gdjs { return getTransparentMaterial(); const resourceName = runtimeObject.getFaceAtIndexResourceName(faceIndex); - if (!resourceName || resourceName === '') { - const material = new THREE.MeshBasicMaterial({ vertexColors: true }); - return material; + if (!resourceName) { + return new THREE.MeshBasicMaterial({ vertexColors: true }); } return runtimeObject .getInstanceContainer() @@ -82,13 +81,9 @@ namespace gdjs { const materials: THREE.Material[] = new Array(6) .fill(0) - .map((_, index) => { - const material: THREE.Material = getFaceMaterial( - runtimeObject, - materialIndexToFaceIndex[index] - ); - return material; - }); + .map((_, index) => + getFaceMaterial(runtimeObject, materialIndexToFaceIndex[index]) + ); const boxMesh = new THREE.Mesh(geometry, materials); @@ -102,15 +97,18 @@ namespace gdjs { this.updateColor(); } updateColor() { - let colors: number[] = []; + const colors: number[] = []; + + const normalizedColor = gdjs + .hexNumberToRGBArray(this._cube3DRuntimeObject._color) + .map((component) => component / 255); - let color = gdjs.hexNumberToRGBArray(this._cube3DRuntimeObject._color); for ( let i = 0; i < this._boxMesh.geometry.attributes.position.count; i++ ) { - colors.push(color[0] / 255, color[1] / 255, color[2] / 255); + colors.push(...normalizedColor); } this._boxMesh.geometry.setAttribute( diff --git a/Extensions/3D/JsExtension.js b/Extensions/3D/JsExtension.js index 7a436b04aafe..35635d58fe75 100644 --- a/Extensions/3D/JsExtension.js +++ b/Extensions/3D/JsExtension.js @@ -2361,6 +2361,7 @@ module.exports = { this._facesOrientation = 'Y'; this._backFaceUpThroughWhichAxisRotation = 'X'; this._shouldUseTransparentTexture = false; + this._color = ''; const geometry = new THREE.BoxGeometry(1, 1, 1); const materials = [ @@ -2386,7 +2387,7 @@ module.exports = { const resourceName = this._faceResourceNames[faceIndex]; - if (!resourceName || resourceName === '') { + if (!resourceName) { return new THREE.MeshBasicMaterial({ vertexColors: true }); } @@ -2421,21 +2422,18 @@ module.exports = { } updateColor(object) { - let colors = []; + const colors = []; - let color; - if (object.content.color) { - color = object.content.color.split(';').map(Number); - } else { - color = [128, 128, 128]; - } + const normalizedColor = objectsRenderingService + .hexNumberToRGBArray(this._cube3DRuntimeObject._color) + .map((component) => component / 255); for ( let i = 0; i < this._threeObject.geometry.attributes.position.count; i++ ) { - colors.push(color[0] / 255, color[1] / 255, color[2] / 255); + colors.push(...normalizedColor); } this._threeObject.geometry.setAttribute( @@ -2476,6 +2474,7 @@ module.exports = { let materialsDirty = false; let uvMappingDirty = false; + let colorDirty = false; const shouldUseTransparentTexture = object.content.enableTextureTransparency; @@ -2483,6 +2482,11 @@ module.exports = { this._shouldUseTransparentTexture = shouldUseTransparentTexture; materialsDirty = true; } + const color = object.content.color; + if (this._color !== color) { + this._color = color; + colorDirty = true; + } const faceResourceNames = [ object.content.frontFaceResourceName, @@ -2575,7 +2579,7 @@ module.exports = { if (materialsDirty) this._updateThreeObjectMaterials(); if (uvMappingDirty) this._updateTextureUvMapping(); - this.updateColor(object); + if (colorDirty) this.updateColor(object); } /** diff --git a/Extensions/JsExtensionTypes.d.ts b/Extensions/JsExtensionTypes.d.ts index 595ae275ac6d..b958d221bab1 100644 --- a/Extensions/JsExtensionTypes.d.ts +++ b/Extensions/JsExtensionTypes.d.ts @@ -189,6 +189,7 @@ declare type ObjectsRenderingService = { objectConfiguration: gd.ObjectConfiguration ) => string; rgbOrHexToHexNumber: (value: string) => number; + hexNumberToRGBArray: (value: string) => [number, number, number]; registerClearCache: (clearCache: (_: any) => void) => void; }; diff --git a/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js b/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js index 4ee215e0c0f6..6a2c74675fa2 100644 --- a/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js +++ b/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js @@ -20,7 +20,11 @@ import * as PIXI_SPINE from 'pixi-spine'; import * as THREE from 'three'; import * as SkeletonUtils from 'three/examples/jsm/utils/SkeletonUtils'; import optionalRequire from '../Utils/OptionalRequire'; -import { rgbOrHexToHexNumber } from '../Utils/ColorTransformer'; +import { + rgbOrHexToHexNumber, + hexNumberToRGBArray, +} from '../Utils/ColorTransformer'; + const path = optionalRequire('path'); const electron = optionalRequire('electron'); const gd: libGDevelop = global.gd; @@ -277,6 +281,7 @@ const ObjectsRenderingService = { } }, rgbOrHexToHexNumber, // Expose a ColorTransformer function, useful to manage different color types for the extensions + hexNumberToRGBArray, // Expose a ColorTransformer function, useful to manage different color types for the extensions gd, // Expose gd so that it can be used by renderers PIXI, // Expose PIXI so that it can be used by renderers THREE, // Expose THREE so that it can be used by renderers diff --git a/newIDE/app/src/Utils/ColorTransformer.js b/newIDE/app/src/Utils/ColorTransformer.js index a46b83dd22f9..2affa681b72a 100644 --- a/newIDE/app/src/Utils/ColorTransformer.js +++ b/newIDE/app/src/Utils/ColorTransformer.js @@ -15,6 +15,16 @@ export const rgbColorToRGBString = (rgbColor: ?RGBColor) => { return `${rgbColor.r};${rgbColor.g};${rgbColor.b}`; }; +export const hexNumberToRGBArray = ( + hexNumber: number +): [integer, integer, integer] => { + return [ + (hexNumber >> 16) & 0xff, + (hexNumber >> 8) & 0xff, + hexNumber & 0xff, + ]; +}; + /** * Convert a RGB color value to a Hex string. * @note No "#" or "0x" are added. From 9e00efb458a5598778ef42754b10aedc654434f1 Mon Sep 17 00:00:00 2001 From: Neyl Date: Wed, 5 Feb 2025 18:36:31 +0100 Subject: [PATCH 11/16] ---- last push for base color WITHOUT tint --- Extensions/3D/JsExtension.js | 11 ++++++----- Extensions/JsExtensionTypes.d.ts | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Extensions/3D/JsExtension.js b/Extensions/3D/JsExtension.js index 35635d58fe75..1415cbae2c1a 100644 --- a/Extensions/3D/JsExtension.js +++ b/Extensions/3D/JsExtension.js @@ -2421,11 +2421,12 @@ module.exports = { this._updateTextureUvMapping(); } - updateColor(object) { + _updateColor() { const colors = []; - const normalizedColor = objectsRenderingService - .hexNumberToRGBArray(this._cube3DRuntimeObject._color) + .hexNumberToRGBArray( + objectsRenderingService.rgbOrHexToHexNumber(this._color) + ) .map((component) => component / 255); for ( @@ -2482,7 +2483,7 @@ module.exports = { this._shouldUseTransparentTexture = shouldUseTransparentTexture; materialsDirty = true; } - const color = object.content.color; + const color = object.content.color || '128;128;128'; if (this._color !== color) { this._color = color; colorDirty = true; @@ -2579,7 +2580,7 @@ module.exports = { if (materialsDirty) this._updateThreeObjectMaterials(); if (uvMappingDirty) this._updateTextureUvMapping(); - if (colorDirty) this.updateColor(object); + if (colorDirty) this._updateColor(); } /** diff --git a/Extensions/JsExtensionTypes.d.ts b/Extensions/JsExtensionTypes.d.ts index b958d221bab1..fcfacbd9a5d7 100644 --- a/Extensions/JsExtensionTypes.d.ts +++ b/Extensions/JsExtensionTypes.d.ts @@ -189,7 +189,7 @@ declare type ObjectsRenderingService = { objectConfiguration: gd.ObjectConfiguration ) => string; rgbOrHexToHexNumber: (value: string) => number; - hexNumberToRGBArray: (value: string) => [number, number, number]; + hexNumberToRGBArray: (value: number) => [number, number, number]; registerClearCache: (clearCache: (_: any) => void) => void; }; From f609bf2762882f2d1ba06024e83a2bdf26efb90c Mon Sep 17 00:00:00 2001 From: Neyl Date: Wed, 5 Feb 2025 19:00:39 +0100 Subject: [PATCH 12/16] Base push for tint experi;ent --- Extensions/3D/Cube3DRuntimeObject.ts | 30 +++++----- .../3D/Cube3DRuntimeObjectPixiRenderer.ts | 18 +++--- Extensions/3D/JsExtension.js | 58 +++++++++---------- .../pixi-renderers/pixi-image-manager.ts | 2 + 4 files changed, 50 insertions(+), 58 deletions(-) diff --git a/Extensions/3D/Cube3DRuntimeObject.ts b/Extensions/3D/Cube3DRuntimeObject.ts index 2c7c859c534b..2edbcb0bb89c 100644 --- a/Extensions/3D/Cube3DRuntimeObject.ts +++ b/Extensions/3D/Cube3DRuntimeObject.ts @@ -24,7 +24,7 @@ namespace gdjs { rightFaceVisible: boolean; topFaceVisible: boolean; bottomFaceVisible: boolean; - color: string; + tint: string; materialType: 'Basic' | 'StandardWithoutMetalness'; }; } @@ -72,7 +72,7 @@ namespace gdjs { ]; _materialType: gdjs.Cube3DRuntimeObject.MaterialType = gdjs.Cube3DRuntimeObject.MaterialType.Basic; - _color: number; + _tint: number; constructor( instanceContainer: gdjs.RuntimeInstanceContainer, objectData: Cube3DObjectData @@ -119,8 +119,8 @@ namespace gdjs { objectData.content.bottomFaceResourceName, ]; - this._color = gdjs.rgbOrHexStringToNumber( - objectData.content.color || '128;128;128' + this._tint = gdjs.rgbOrHexStringToNumber( + objectData.content.tint || '128;128;128' ); this._materialType = this._convertMaterialType( @@ -212,11 +212,11 @@ namespace gdjs { this._faceResourceNames[faceIndex] = resourceName; this._renderer.updateFace(faceIndex); } - setColor(color: string): void { - const colorinHex = gdjs.rgbOrHexStringToNumber(color); - if (colorinHex === this._color) return; - this._color = colorinHex; - this._renderer.updateColor(); + setTint(tint: string): void { + const tintInHex = gdjs.rgbOrHexStringToNumber(tint); + if (tintInHex === this._tint) return; + this._tint = tintInHex; + this._renderer.updateTint(); } /** @internal */ @@ -302,8 +302,8 @@ namespace gdjs { newObjectData.content.frontFaceResourceName ); } - if (oldObjectData.content.color !== newObjectData.content.color) { - this.setColor(newObjectData.content.color); + if (oldObjectData.content.tint !== newObjectData.content.tint) { + this.setTint(newObjectData.content.tint); } if ( @@ -438,7 +438,7 @@ namespace gdjs { vfb: this._visibleFacesBitmask, trfb: this._textureRepeatFacesBitmask, frn: this._faceResourceNames, - c: this._color, + c: this._tint, }; } @@ -493,9 +493,9 @@ namespace gdjs { } } if (networkSyncData.c !== undefined) { - if (this._color !== networkSyncData.c) { - this._color = networkSyncData.c; - this._renderer.updateColor(); + if (this._tint !== networkSyncData.c) { + this._tint = networkSyncData.c; + this._renderer.updateTint(); } } } diff --git a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts index eb92de06e2b0..2438299f9553 100644 --- a/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts +++ b/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.ts @@ -53,10 +53,6 @@ namespace gdjs { if (!runtimeObject.isFaceAtIndexVisible(faceIndex)) return getTransparentMaterial(); - const resourceName = runtimeObject.getFaceAtIndexResourceName(faceIndex); - if (!resourceName) { - return new THREE.MeshBasicMaterial({ vertexColors: true }); - } return runtimeObject .getInstanceContainer() .getGame() @@ -94,13 +90,13 @@ namespace gdjs { this.updateSize(); this.updatePosition(); this.updateRotation(); - this.updateColor(); + this.updateTint(); } - updateColor() { - const colors: number[] = []; + updateTint() { + const tints: number[] = []; - const normalizedColor = gdjs - .hexNumberToRGBArray(this._cube3DRuntimeObject._color) + const normalizedTint = gdjs + .hexNumberToRGBArray(this._cube3DRuntimeObject._tint) .map((component) => component / 255); for ( @@ -108,12 +104,12 @@ namespace gdjs { i < this._boxMesh.geometry.attributes.position.count; i++ ) { - colors.push(...normalizedColor); + tints.push(...normalizedTint); } this._boxMesh.geometry.setAttribute( 'color', - new THREE.BufferAttribute(new Float32Array(colors), 3) + new THREE.BufferAttribute(new Float32Array(tints), 3) ); } diff --git a/Extensions/3D/JsExtension.js b/Extensions/3D/JsExtension.js index 1415cbae2c1a..c35ca9a61769 100644 --- a/Extensions/3D/JsExtension.js +++ b/Extensions/3D/JsExtension.js @@ -823,7 +823,7 @@ module.exports = { propertyName === 'backFaceUpThroughWhichAxisRotation' || propertyName === 'facesOrientation' || propertyName === 'materialType' || - propertyName === 'color' + propertyName === 'tint' ) { objectContent[propertyName] = newValue; return true; @@ -904,10 +904,10 @@ module.exports = { .setMeasurementUnit(gd.MeasurementUnit.getPixel()) .setGroup(_('Default size')); objectProperties - .getOrCreate('color') - .setValue(objectContent.color || '128;128;128') + .getOrCreate('tint') + .setValue(objectContent.tint || '128;128;128') .setType('Color') - .setLabel(_('Color')) + .setLabel(_('Tint')) .setGroup(_('Texture')); objectProperties @@ -1099,7 +1099,7 @@ module.exports = { topFaceResourceRepeat: false, bottomFaceResourceRepeat: false, materialType: 'Basic', - color: '128;128;128', + tint: '128;128;128', }; Cube3DObject.updateInitialInstanceProperty = function ( @@ -1578,18 +1578,18 @@ module.exports = { object .addScopedAction( - 'SetColor', - _('Color'), - _('Change the color of the cube.'), - _('Change the color of _PARAM0_ to _PARAM1_'), - _('Color'), + 'SetTint', + _('Tint'), + _('Change the tint of the cube.'), + _('Change the tint of _PARAM0_ to _PARAM1_'), + _('Tint'), 'res/actions/color24.png', 'res/actions/color.png' ) .addParameter('object', _('3D Cube'), 'Cube3DObject', false) - .addParameter('color', _('Color'), '', false) + .addParameter('color', _('Tint'), '', false) .getCodeExtraInformation() - .setFunctionName('setColor'); + .setFunctionName('setTint'); extension .addExpressionAndConditionAndAction( @@ -2361,7 +2361,7 @@ module.exports = { this._facesOrientation = 'Y'; this._backFaceUpThroughWhichAxisRotation = 'X'; this._shouldUseTransparentTexture = false; - this._color = ''; + this._tint = ''; const geometry = new THREE.BoxGeometry(1, 1, 1); const materials = [ @@ -2385,16 +2385,10 @@ module.exports = { return getTransparentMaterial(); } - const resourceName = this._faceResourceNames[faceIndex]; - - if (!resourceName) { - return new THREE.MeshBasicMaterial({ vertexColors: true }); - } - // Utilisation du loader de ressources pour obtenir le matériau return await this._pixiResourcesLoader.getThreeMaterial( project, - resourceName, + this._faceResourceNames[faceIndex], { useTransparentTexture: this._shouldUseTransparentTexture, } @@ -2421,11 +2415,11 @@ module.exports = { this._updateTextureUvMapping(); } - _updateColor() { - const colors = []; - const normalizedColor = objectsRenderingService + _updateTint() { + const tints = []; + const normalizedTint = objectsRenderingService .hexNumberToRGBArray( - objectsRenderingService.rgbOrHexToHexNumber(this._color) + objectsRenderingService.rgbOrHexToHexNumber(this._tint) ) .map((component) => component / 255); @@ -2434,12 +2428,12 @@ module.exports = { i < this._threeObject.geometry.attributes.position.count; i++ ) { - colors.push(...normalizedColor); + tints.push(...normalizedTint); } this._threeObject.geometry.setAttribute( 'color', - new THREE.BufferAttribute(new Float32Array(colors), 3) + new THREE.BufferAttribute(new Float32Array(tints), 3) ); } @@ -2475,7 +2469,7 @@ module.exports = { let materialsDirty = false; let uvMappingDirty = false; - let colorDirty = false; + let tintDirty = false; const shouldUseTransparentTexture = object.content.enableTextureTransparency; @@ -2483,10 +2477,10 @@ module.exports = { this._shouldUseTransparentTexture = shouldUseTransparentTexture; materialsDirty = true; } - const color = object.content.color || '128;128;128'; - if (this._color !== color) { - this._color = color; - colorDirty = true; + const tint = object.content.tint || '128;128;128'; + if (this._tint !== tint) { + this._tint = tint; + tintDirty = true; } const faceResourceNames = [ @@ -2580,7 +2574,7 @@ module.exports = { if (materialsDirty) this._updateThreeObjectMaterials(); if (uvMappingDirty) this._updateTextureUvMapping(); - if (colorDirty) this._updateColor(); + if (tintDirty) this._updateTint(); } /** diff --git a/GDJS/Runtime/pixi-renderers/pixi-image-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-image-manager.ts index 03cb6091f7b6..c68f40143b7f 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-image-manager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-image-manager.ts @@ -242,12 +242,14 @@ namespace gdjs { map: this.getThreeTexture(resourceName), side: useTransparentTexture ? THREE.DoubleSide : THREE.FrontSide, transparent: useTransparentTexture, + vertexColors: true, }) : new THREE.MeshStandardMaterial({ map: this.getThreeTexture(resourceName), side: useTransparentTexture ? THREE.DoubleSide : THREE.FrontSide, transparent: useTransparentTexture, metalness: 0, + vertexColors: true, }); this._loadedThreeMaterials.put(cacheKey, material); return material; From f22e3fc0679fca686e62f51c57f19c01ba22fdcd Mon Sep 17 00:00:00 2001 From: Neyl Date: Thu, 6 Feb 2025 10:28:06 +0100 Subject: [PATCH 13/16] supported tint in editor --- Extensions/3D/Cube3DRuntimeObject.ts | 2 +- Extensions/3D/JsExtension.js | 6 +++--- newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Extensions/3D/Cube3DRuntimeObject.ts b/Extensions/3D/Cube3DRuntimeObject.ts index 2edbcb0bb89c..d2a854798933 100644 --- a/Extensions/3D/Cube3DRuntimeObject.ts +++ b/Extensions/3D/Cube3DRuntimeObject.ts @@ -120,7 +120,7 @@ namespace gdjs { ]; this._tint = gdjs.rgbOrHexStringToNumber( - objectData.content.tint || '128;128;128' + objectData.content.tint || '255;255;255' ); this._materialType = this._convertMaterialType( diff --git a/Extensions/3D/JsExtension.js b/Extensions/3D/JsExtension.js index c35ca9a61769..55a07be72be1 100644 --- a/Extensions/3D/JsExtension.js +++ b/Extensions/3D/JsExtension.js @@ -905,7 +905,7 @@ module.exports = { .setGroup(_('Default size')); objectProperties .getOrCreate('tint') - .setValue(objectContent.tint || '128;128;128') + .setValue(objectContent.tint || '255;255;255') .setType('Color') .setLabel(_('Tint')) .setGroup(_('Texture')); @@ -1099,7 +1099,7 @@ module.exports = { topFaceResourceRepeat: false, bottomFaceResourceRepeat: false, materialType: 'Basic', - tint: '128;128;128', + tint: '255;255;255', }; Cube3DObject.updateInitialInstanceProperty = function ( @@ -2477,7 +2477,7 @@ module.exports = { this._shouldUseTransparentTexture = shouldUseTransparentTexture; materialsDirty = true; } - const tint = object.content.tint || '128;128;128'; + const tint = object.content.tint || '255;255;255'; if (this._tint !== tint) { this._tint = tint; tintDirty = true; diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index cb0789d4aad6..c2321f3d9d1b 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -583,6 +583,7 @@ export default class PixiResourcesLoader { map: texture, side: useTransparentTexture ? THREE.DoubleSide : THREE.FrontSide, transparent: useTransparentTexture, + vertexColors:true, }); return material; From 0da2fadc3facaeba54ba7d525c39184446508481 Mon Sep 17 00:00:00 2001 From: Neyl Date: Thu, 6 Feb 2025 10:41:05 +0100 Subject: [PATCH 14/16] format + naming --- Extensions/3D/Cube3DRuntimeObject.ts | 4 ++-- newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js | 2 +- newIDE/app/src/Utils/ColorTransformer.js | 6 +----- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Extensions/3D/Cube3DRuntimeObject.ts b/Extensions/3D/Cube3DRuntimeObject.ts index d2a854798933..ee82286bd8db 100644 --- a/Extensions/3D/Cube3DRuntimeObject.ts +++ b/Extensions/3D/Cube3DRuntimeObject.ts @@ -45,7 +45,7 @@ namespace gdjs { trfb: integer; frn: [string, string, string, string, string, string]; mt: number; - c: number; + tint: number; }; type Cube3DObjectNetworkSyncData = Object3DNetworkSyncData & @@ -438,7 +438,7 @@ namespace gdjs { vfb: this._visibleFacesBitmask, trfb: this._textureRepeatFacesBitmask, frn: this._faceResourceNames, - c: this._tint, + tint: this._tint, }; } diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index c2321f3d9d1b..4fcee216748e 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -583,7 +583,7 @@ export default class PixiResourcesLoader { map: texture, side: useTransparentTexture ? THREE.DoubleSide : THREE.FrontSide, transparent: useTransparentTexture, - vertexColors:true, + vertexColors: true, }); return material; diff --git a/newIDE/app/src/Utils/ColorTransformer.js b/newIDE/app/src/Utils/ColorTransformer.js index 2affa681b72a..54adc9016c14 100644 --- a/newIDE/app/src/Utils/ColorTransformer.js +++ b/newIDE/app/src/Utils/ColorTransformer.js @@ -18,11 +18,7 @@ export const rgbColorToRGBString = (rgbColor: ?RGBColor) => { export const hexNumberToRGBArray = ( hexNumber: number ): [integer, integer, integer] => { - return [ - (hexNumber >> 16) & 0xff, - (hexNumber >> 8) & 0xff, - hexNumber & 0xff, - ]; + return [(hexNumber >> 16) & 0xff, (hexNumber >> 8) & 0xff, hexNumber & 0xff]; }; /** From 1ef8d8e0f0fb8654ad24d65cd1ec8f96390380cb Mon Sep 17 00:00:00 2001 From: Neyl Date: Thu, 6 Feb 2025 10:50:17 +0100 Subject: [PATCH 15/16] typing error fixed + forgotten changes --- Extensions/3D/Cube3DRuntimeObject.ts | 6 +++--- newIDE/app/src/Utils/ColorTransformer.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Extensions/3D/Cube3DRuntimeObject.ts b/Extensions/3D/Cube3DRuntimeObject.ts index ee82286bd8db..b890d57b7279 100644 --- a/Extensions/3D/Cube3DRuntimeObject.ts +++ b/Extensions/3D/Cube3DRuntimeObject.ts @@ -492,9 +492,9 @@ namespace gdjs { } } } - if (networkSyncData.c !== undefined) { - if (this._tint !== networkSyncData.c) { - this._tint = networkSyncData.c; + if (networkSyncData.tint !== undefined) { + if (this._tint !== networkSyncData.tint) { + this._tint = networkSyncData.tint; this._renderer.updateTint(); } } diff --git a/newIDE/app/src/Utils/ColorTransformer.js b/newIDE/app/src/Utils/ColorTransformer.js index 54adc9016c14..f9102bcac83e 100644 --- a/newIDE/app/src/Utils/ColorTransformer.js +++ b/newIDE/app/src/Utils/ColorTransformer.js @@ -17,7 +17,7 @@ export const rgbColorToRGBString = (rgbColor: ?RGBColor) => { export const hexNumberToRGBArray = ( hexNumber: number -): [integer, integer, integer] => { +): [number, number, number] => { return [(hexNumber >> 16) & 0xff, (hexNumber >> 8) & 0xff, hexNumber & 0xff]; }; From 1bb71a3137f5e50adf9a6aa50b3128d01b5987f6 Mon Sep 17 00:00:00 2001 From: Neyl Date: Thu, 6 Feb 2025 10:58:48 +0100 Subject: [PATCH 16/16] useless comment delete --- Extensions/3D/JsExtension.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Extensions/3D/JsExtension.js b/Extensions/3D/JsExtension.js index 55a07be72be1..ad6b8e9d4a81 100644 --- a/Extensions/3D/JsExtension.js +++ b/Extensions/3D/JsExtension.js @@ -2385,7 +2385,6 @@ module.exports = { return getTransparentMaterial(); } - // Utilisation du loader de ressources pour obtenir le matériau return await this._pixiResourcesLoader.getThreeMaterial( project, this._faceResourceNames[faceIndex],