Browse Source

Merge pull request #242 from sukolsak/export-overpaint

Add overpaint support to geometry exporters
David Sehnal 3 years ago
parent
commit
195668760e

+ 1 - 0
CHANGELOG.md

@@ -11,6 +11,7 @@ Note that since we don't clearly distinguish between a public and private interf
 - Fix coordinateSystem not handled in ``Structure.asParent``
 - Add dynamicBonds to ``Structure`` props (force re-calc on model change)
     - Expose as optional param in root structure transform helper
+- Add overpaint support to geometry exporters
 
 ## [v2.2.0] - 2021-07-31
 

+ 4 - 38
src/extensions/geo-export/glb-exporter.ts

@@ -126,11 +126,8 @@ export class GlbExporter extends MeshExporter<GlbData> {
         };
     }
 
-    private addColorBuffer(values: BaseValues, groups: Float32Array | Uint8Array, vertexCount: number, instanceIndex: number, isGeoTexture: boolean, interpolatedColors: Uint8Array) {
+    private addColorBuffer(values: BaseValues, groups: Float32Array | Uint8Array, vertexCount: number, instanceIndex: number, isGeoTexture: boolean, interpolatedColors: Uint8Array | undefined) {
         const groupCount = values.uGroupCount.ref.value;
-        const colorType = values.dColorType.ref.value;
-        const uColor = values.uColor.ref.value;
-        const tColor = values.tColor.ref.value.array;
         const uAlpha = values.uAlpha.ref.value;
         const dTransparency = values.dTransparency.ref.value;
         const tTransparency = values.tTransparency.ref.value;
@@ -138,38 +135,7 @@ export class GlbExporter extends MeshExporter<GlbData> {
         const colorArray = new Uint8Array(vertexCount * 4);
 
         for (let i = 0; i < vertexCount; ++i) {
-            let color: Color;
-            switch (colorType) {
-                case 'uniform':
-                    color = Color.fromNormalizedArray(uColor, 0);
-                    break;
-                case 'instance':
-                    color = Color.fromArray(tColor, instanceIndex * 3);
-                    break;
-                case 'group': {
-                    const group = isGeoTexture ? GlbExporter.getGroup(groups, i) : groups[i];
-                    color = Color.fromArray(tColor, group * 3);
-                    break;
-                }
-                case 'groupInstance': {
-                    const group = isGeoTexture ? GlbExporter.getGroup(groups, i) : groups[i];
-                    color = Color.fromArray(tColor, (instanceIndex * groupCount + group) * 3);
-                    break;
-                }
-                case 'vertex':
-                    color = Color.fromArray(tColor, i * 3);
-                    break;
-                case 'vertexInstance':
-                    color = Color.fromArray(tColor, (instanceIndex * vertexCount + i) * 3);
-                    break;
-                case 'volume':
-                    color = Color.fromArray(interpolatedColors!, i * 3);
-                    break;
-                case 'volumeInstance':
-                    color = Color.fromArray(interpolatedColors!, (instanceIndex * vertexCount + i) * 3);
-                    break;
-                default: throw new Error('Unsupported color type.');
-            }
+            let color = GlbExporter.getColor(values, groups, vertexCount, instanceIndex, isGeoTexture, interpolatedColors, i);
 
             let alpha = uAlpha;
             if (dTransparency) {
@@ -201,7 +167,7 @@ export class GlbExporter extends MeshExporter<GlbData> {
         const aTransform = values.aTransform.ref.value;
         const instanceCount = values.uInstanceCount.ref.value;
 
-        let interpolatedColors: Uint8Array;
+        let interpolatedColors: Uint8Array | undefined;
         if (colorType === 'volume' || colorType === 'volumeInstance') {
             const stride = isGeoTexture ? 4 : 3;
             interpolatedColors = GlbExporter.getInterpolatedColors(mesh!.vertices, mesh!.vertexCount, values, stride, colorType, webgl!);
@@ -235,7 +201,7 @@ export class GlbExporter extends MeshExporter<GlbData> {
 
                 // create a color buffer if needed
                 if (instanceIndex === 0 || !sameColorBuffer) {
-                    colorAccessorIndex = this.addColorBuffer(values, groups, vertexCount, instanceIndex, isGeoTexture, interpolatedColors!);
+                    colorAccessorIndex = this.addColorBuffer(values, groups, vertexCount, instanceIndex, isGeoTexture, interpolatedColors);
                 }
 
                 // glTF mesh

+ 51 - 0
src/extensions/geo-export/mesh-exporter.ts

@@ -194,6 +194,57 @@ export abstract class MeshExporter<D extends RenderObjectExportData> implements
         }
     }
 
+    protected static getColor(values: BaseValues, groups: Float32Array | Uint8Array, vertexCount: number, instanceIndex: number, isGeoTexture: boolean, interpolatedColors: Uint8Array | undefined, vertexIndex: number): Color {
+        const groupCount = values.uGroupCount.ref.value;
+        const colorType = values.dColorType.ref.value;
+        const uColor = values.uColor.ref.value;
+        const tColor = values.tColor.ref.value.array;
+        const dOverpaint = values.dOverpaint.ref.value;
+        const tOverpaint = values.tOverpaint.ref.value.array;
+
+        let color: Color;
+        switch (colorType) {
+            case 'uniform':
+                color = Color.fromNormalizedArray(uColor, 0);
+                break;
+            case 'instance':
+                color = Color.fromArray(tColor, instanceIndex * 3);
+                break;
+            case 'group': {
+                const group = isGeoTexture ? MeshExporter.getGroup(groups, vertexIndex) : groups[vertexIndex];
+                color = Color.fromArray(tColor, group * 3);
+                break;
+            }
+            case 'groupInstance': {
+                const group = isGeoTexture ? MeshExporter.getGroup(groups, vertexIndex) : groups[vertexIndex];
+                color = Color.fromArray(tColor, (instanceIndex * groupCount + group) * 3);
+                break;
+            }
+            case 'vertex':
+                color = Color.fromArray(tColor, vertexIndex * 3);
+                break;
+            case 'vertexInstance':
+                color = Color.fromArray(tColor, (instanceIndex * vertexCount + vertexIndex) * 3);
+                break;
+            case 'volume':
+                color = Color.fromArray(interpolatedColors!, vertexIndex * 3);
+                break;
+            case 'volumeInstance':
+                color = Color.fromArray(interpolatedColors!, (instanceIndex * vertexCount + vertexIndex) * 3);
+                break;
+            default: throw new Error('Unsupported color type.');
+        }
+
+        if (dOverpaint) {
+            const group = isGeoTexture ? MeshExporter.getGroup(groups, vertexIndex) : groups[vertexIndex];
+            const overpaintColor = Color.fromArray(tOverpaint, (instanceIndex * groupCount + group) * 4);
+            const overpaintAlpha = tOverpaint[(instanceIndex * groupCount + group) * 4 + 3] / 255;
+            color = Color.interpolate(color, overpaintColor, overpaintAlpha);
+        }
+
+        return color;
+    }
+
     protected abstract addMeshWithColors(input: AddMeshInput): void;
 
     private async addMesh(values: MeshValues, webgl: WebGLContext, ctx: RuntimeContext) {

+ 3 - 34
src/extensions/geo-export/obj-exporter.ts

@@ -79,14 +79,13 @@ export class ObjExporter extends MeshExporter<ObjData> {
 
         const groupCount = values.uGroupCount.ref.value;
         const colorType = values.dColorType.ref.value;
-        const tColor = values.tColor.ref.value.array;
         const uAlpha = values.uAlpha.ref.value;
         const dTransparency = values.dTransparency.ref.value;
         const tTransparency = values.tTransparency.ref.value;
         const aTransform = values.aTransform.ref.value;
         const instanceCount = values.uInstanceCount.ref.value;
 
-        let interpolatedColors: Uint8Array;
+        let interpolatedColors: Uint8Array | undefined;
         if (colorType === 'volume' || colorType === 'volumeInstance') {
             interpolatedColors = ObjExporter.getInterpolatedColors(mesh!.vertices, mesh!.vertexCount, values, stride, colorType, webgl!);
             ObjExporter.quantizeColors(interpolatedColors, mesh!.vertexCount);
@@ -129,38 +128,8 @@ export class ObjExporter extends MeshExporter<ObjData> {
 
             // face
             for (let i = 0; i < drawCount; i += 3) {
-                let color: Color;
-                switch (colorType) {
-                    case 'uniform':
-                        color = Color.fromNormalizedArray(values.uColor.ref.value, 0);
-                        break;
-                    case 'instance':
-                        color = Color.fromArray(tColor, instanceIndex * 3);
-                        break;
-                    case 'group': {
-                        const group = isGeoTexture ? ObjExporter.getGroup(groups, i) : groups[indices![i]];
-                        color = Color.fromArray(tColor, group * 3);
-                        break;
-                    }
-                    case 'groupInstance': {
-                        const group = isGeoTexture ? ObjExporter.getGroup(groups, i) : groups[indices![i]];
-                        color = Color.fromArray(tColor, (instanceIndex * groupCount + group) * 3);
-                        break;
-                    }
-                    case 'vertex':
-                        color = Color.fromArray(tColor, indices![i] * 3);
-                        break;
-                    case 'vertexInstance':
-                        color = Color.fromArray(tColor, (instanceIndex * vertexCount + indices![i]) * 3);
-                        break;
-                    case 'volume':
-                        color = Color.fromArray(interpolatedColors!, (isGeoTexture ? i : indices![i]) * 3);
-                        break;
-                    case 'volumeInstance':
-                        color = Color.fromArray(interpolatedColors!, (instanceIndex * vertexCount + (isGeoTexture ? i : indices![i])) * 3);
-                        break;
-                    default: throw new Error('Unsupported color type.');
-                }
+                const v = isGeoTexture ? i : indices![i];
+                const color = ObjExporter.getColor(values, groups, vertexCount, instanceIndex, isGeoTexture, interpolatedColors, v);
 
                 let alpha = uAlpha;
                 if (dTransparency) {

+ 3 - 34
src/extensions/geo-export/usdz-exporter.ts

@@ -70,14 +70,13 @@ def Material "material${materialKey}"
 
         const groupCount = values.uGroupCount.ref.value;
         const colorType = values.dColorType.ref.value;
-        const tColor = values.tColor.ref.value.array;
         const uAlpha = values.uAlpha.ref.value;
         const dTransparency = values.dTransparency.ref.value;
         const tTransparency = values.tTransparency.ref.value;
         const aTransform = values.aTransform.ref.value;
         const instanceCount = values.uInstanceCount.ref.value;
 
-        let interpolatedColors: Uint8Array;
+        let interpolatedColors: Uint8Array | undefined;
         if (colorType === 'volume' || colorType === 'volumeInstance') {
             interpolatedColors = UsdzExporter.getInterpolatedColors(mesh!.vertices, mesh!.vertexCount, values, stride, colorType, webgl!);
             UsdzExporter.quantizeColors(interpolatedColors, mesh!.vertexCount);
@@ -132,38 +131,8 @@ def Material "material${materialKey}"
             // color
             const faceIndicesByMaterial = new Map<number, number[]>();
             for (let i = 0; i < drawCount; i += 3) {
-                let color: Color;
-                switch (colorType) {
-                    case 'uniform':
-                        color = Color.fromNormalizedArray(values.uColor.ref.value, 0);
-                        break;
-                    case 'instance':
-                        color = Color.fromArray(tColor, instanceIndex * 3);
-                        break;
-                    case 'group': {
-                        const group = isGeoTexture ? UsdzExporter.getGroup(groups, i) : groups[indices![i]];
-                        color = Color.fromArray(tColor, group * 3);
-                        break;
-                    }
-                    case 'groupInstance': {
-                        const group = isGeoTexture ? UsdzExporter.getGroup(groups, i) : groups[indices![i]];
-                        color = Color.fromArray(tColor, (instanceIndex * groupCount + group) * 3);
-                        break;
-                    }
-                    case 'vertex':
-                        color = Color.fromArray(tColor, indices![i] * 3);
-                        break;
-                    case 'vertexInstance':
-                        color = Color.fromArray(tColor, (instanceIndex * vertexCount + indices![i]) * 3);
-                        break;
-                    case 'volume':
-                        color = Color.fromArray(interpolatedColors!, (isGeoTexture ? i : indices![i]) * 3);
-                        break;
-                    case 'volumeInstance':
-                        color = Color.fromArray(interpolatedColors!, (instanceIndex * vertexCount + (isGeoTexture ? i : indices![i])) * 3);
-                        break;
-                    default: throw new Error('Unsupported color type.');
-                }
+                const v = isGeoTexture ? i : indices![i];
+                const color = UsdzExporter.getColor(values, groups, vertexCount, instanceIndex, isGeoTexture, interpolatedColors, v);
 
                 let alpha = uAlpha;
                 if (dTransparency) {