Ver Fonte

check if renderable transform matrix has reflection

- force double-sided draw to ensure the front is drawn
Alexander Rose há 4 anos atrás
pai
commit
431ba01117

+ 1 - 0
src/mol-canvas3d/helper/bounding-sphere-helper.ts

@@ -67,6 +67,7 @@ export class BoundingSphereHelper {
                 uInstanceCount: ro.values.uInstanceCount,
                 instanceCount: ro.values.instanceCount,
                 aInstance: ro.values.aInstance,
+                hasReflection: ro.values.hasReflection,
             });
             if (newInstanceData) this.instancesData.set(ro, newInstanceData);
         });

+ 20 - 3
src/mol-geo/geometry/transform-data.ts

@@ -1,11 +1,11 @@
 /**
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
 import { ValueCell } from '../../mol-util';
-import { Mat4 } from '../../mol-math/linear-algebra';
+import { Mat4, Mat3 } from '../../mol-math/linear-algebra';
 import { fillSerial } from '../../mol-util/array';
 
 export type TransformData = {
@@ -24,9 +24,23 @@ export type TransformData = {
     uInstanceCount: ValueCell<number>,
     instanceCount: ValueCell<number>,
     aInstance: ValueCell<Float32Array>,
+
+    hasReflection: ValueCell<boolean>,
+}
+
+const _m3 = Mat3();
+const _m4 = Mat4();
+function checkReflection(transformArray: Float32Array, instanceCount: number) {
+    for (let i = 0; i < instanceCount; i++) {
+        Mat3.fromMat4(_m3, Mat4.fromArray(_m4, transformArray, i * 16));
+        if (Mat3.determinant(_m3) < 0) return true;
+    }
+    return false;
 }
 
 export function createTransform(transformArray: Float32Array, instanceCount: number, transformData?: TransformData): TransformData {
+    const hasReflection = checkReflection(transformArray, instanceCount);
+
     if (transformData) {
         ValueCell.update(transformData.matrix, transformData.matrix.ref.value);
         ValueCell.update(transformData.transform, transformArray);
@@ -44,6 +58,8 @@ export function createTransform(transformArray: Float32Array, instanceCount: num
         const aInstance = transformData.aInstance.ref.value.length >= instanceCount ? transformData.aInstance.ref.value : new Float32Array(instanceCount);
         ValueCell.update(transformData.aInstance, fillSerial(aInstance, instanceCount));
 
+        ValueCell.update(transformData.hasReflection, hasReflection);
+
         updateTransformData(transformData);
         return transformData;
     } else {
@@ -54,7 +70,8 @@ export function createTransform(transformArray: Float32Array, instanceCount: num
             extraTransform: ValueCell.create(fillIdentityTransform(new Float32Array(instanceCount * 16), instanceCount)),
             uInstanceCount: ValueCell.create(instanceCount),
             instanceCount: ValueCell.create(instanceCount),
-            aInstance: ValueCell.create(fillSerial(new Float32Array(instanceCount)))
+            aInstance: ValueCell.create(fillSerial(new Float32Array(instanceCount))),
+            hasReflection: ValueCell.create(hasReflection),
         };
     }
 }

+ 1 - 0
src/mol-gl/_spec/renderer.spec.ts

@@ -78,6 +78,7 @@ function createPoints() {
         matrix: ValueCell.create(m4),
         transform,
         extraTransform,
+        hasReflection: ValueCell.create(false),
         boundingSphere,
         invariantBoundingSphere,
 

+ 1 - 0
src/mol-gl/renderable/direct-volume.ts

@@ -50,6 +50,7 @@ export const DirectVolumeSchema = {
     matrix: ValueSpec('m4'),
     transform: ValueSpec('float32'),
     extraTransform: ValueSpec('float32'),
+    hasReflection: ValueSpec('boolean'),
 
     boundingSphere: ValueSpec('sphere'),
     invariantBoundingSphere: ValueSpec('sphere'),

+ 2 - 0
src/mol-gl/renderable/schema.ts

@@ -253,6 +253,8 @@ export const BaseSchema = {
     transform: ValueSpec('float32'),
     /** additional per-instance transform, see aTransform */
     extraTransform: ValueSpec('float32'),
+    /** denotes reflection in transform */
+    hasReflection: ValueSpec('boolean'),
 
     /** bounding sphere taking aTransform into account and encompases all instances */
     boundingSphere: ValueSpec('sphere'),

+ 1 - 1
src/mol-gl/renderer.ts

@@ -262,7 +262,7 @@ namespace Renderer {
             }
 
             if (r.values.dDoubleSided) {
-                if (r.values.dDoubleSided.ref.value) {
+                if (r.values.dDoubleSided.ref.value || r.values.hasReflection.ref.value) {
                     state.disable(gl.CULL_FACE);
                 } else {
                     state.enable(gl.CULL_FACE);