Browse Source

wip, repr transform

Alexander Rose 6 years ago
parent
commit
d0a39e944a

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

@@ -56,6 +56,7 @@ export class BoundingSphereHelper {
                 const instanceData = this.instancesData.get(ro)
                 const newInstanceData = updateBoundingSphereData(this.scene, r.invariantBoundingSphere, instanceData, ColorNames.skyblue, {
                     aTransform: ro.values.aTransform,
+                    transform: ro.values.transform,
                     uInstanceCount: ro.values.uInstanceCount,
                     instanceCount: ro.values.instanceCount,
                     aInstance: ro.values.aInstance,

+ 15 - 0
src/mol-geo/geometry/transform-data.ts

@@ -10,6 +10,7 @@ import { fillSerial } from 'mol-util/array';
 
 export type TransformData = {
     aTransform: ValueCell<Float32Array>,
+    transform: ValueCell<Float32Array>,
     uInstanceCount: ValueCell<number>,
     instanceCount: ValueCell<number>,
     aInstance: ValueCell<Float32Array>,
@@ -26,6 +27,7 @@ export function createTransform(transformArray: Float32Array, instanceCount: num
     } else {
         return {
             aTransform: ValueCell.create(transformArray),
+            transform: ValueCell.create(new Float32Array(transformArray)),
             uInstanceCount: ValueCell.create(instanceCount),
             instanceCount: ValueCell.create(instanceCount),
             aInstance: ValueCell.create(fillSerial(new Float32Array(instanceCount)))
@@ -37,4 +39,17 @@ const identityTransform = new Float32Array(16)
 Mat4.toArray(Mat4.identity(), identityTransform, 0)
 export function createIdentityTransform(transformData?: TransformData): TransformData {
     return createTransform(identityTransform, 1, transformData)
+}
+
+const tmpTransformMat4 = Mat4.identity()
+export function setTransform(matrix: Mat4, transformData: TransformData) {
+    const instanceCount = transformData.instanceCount.ref.value
+    const transform = transformData.transform.ref.value
+    const aTransform = transformData.aTransform.ref.value
+    for (let i = 0; i < instanceCount; i++) {
+        Mat4.fromArray(tmpTransformMat4, transform, i * 16)
+        Mat4.mul(tmpTransformMat4, tmpTransformMat4, matrix)
+        Mat4.toArray(tmpTransformMat4, aTransform, i * 16)
+    }
+    ValueCell.update(transformData.aTransform, aTransform)
 }

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

@@ -56,6 +56,7 @@ function createPoints() {
     const aTransform = ValueCell.create(new Float32Array(16))
     const m4 = Mat4.identity()
     Mat4.toArray(m4, aTransform.ref.value, 0)
+    const transform = ValueCell.create(new Float32Array(aTransform.ref.value))
 
     const boundingSphere = ValueCell.create(Sphere3D.create(Vec3.zero(), 2))
     const invariantBoundingSphere = ValueCell.create(Sphere3D.create(Vec3.zero(), 2))
@@ -77,6 +78,7 @@ function createPoints() {
 
         drawCount: ValueCell.create(3),
         instanceCount: ValueCell.create(1),
+        transform,
         boundingSphere,
         invariantBoundingSphere,
 

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

@@ -28,6 +28,7 @@ export const DirectVolumeSchema = {
 
     drawCount: ValueSpec('number'),
     instanceCount: ValueSpec('number'),
+    transform: AttributeSpec('float32', 16, 1),
     boundingSphere: ValueSpec('sphere'),
     invariantBoundingSphere: ValueSpec('sphere'),
 

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

@@ -198,6 +198,7 @@ export const BaseSchema = {
 
     drawCount: ValueSpec('number'),
     instanceCount: ValueSpec('number'),
+    transform: AttributeSpec('float32', 16, 1),
     boundingSphere: ValueSpec('sphere'),
     invariantBoundingSphere: ValueSpec('sphere'),
 

+ 5 - 0
src/mol-repr/representation.ts

@@ -106,9 +106,13 @@ interface Representation<D, P extends PD.Params = {}> {
 }
 namespace Representation {
     export interface State {
+        /** Controls if the representation's renderobjects are rendered or not */
         visible: boolean
+        /** Controls if the representation's renderobjects are pickable or not */
         pickable: boolean
+        /** Controls if the representation's renderobjects are synced automatically with GPU or not */
         syncManually: boolean
+        /** A transformation applied to the representation's renderobjects */
         transform: Mat4
     }
     export function createState() {
@@ -255,5 +259,6 @@ export interface Visual<D, P extends PD.Params> {
     mark: (loci: Loci, action: MarkerAction) => boolean
     setVisibility: (value: boolean) => void
     setPickable: (value: boolean) => void
+    setTransform: (value: Mat4) => void
     destroy: () => void
 }

+ 1 - 0
src/mol-repr/structure/complex-representation.ts

@@ -55,6 +55,7 @@ export function ComplexRepresentation<P extends StructureParams>(label: string,
     function setState(state: Partial<Representation.State>) {
         if (state.visible !== undefined && visual) visual.setVisibility(state.visible)
         if (state.pickable !== undefined && visual) visual.setPickable(state.pickable)
+        if (state.transform !== undefined && visual) visual.setTransform(state.transform)
 
         Representation.updateState(_state, state)
     }

+ 5 - 0
src/mol-repr/structure/complex-visual.ts

@@ -28,6 +28,8 @@ import { SizeTheme } from 'mol-theme/size';
 import { RenderableState } from 'mol-gl/renderable';
 import { UnitsParams } from './units-representation';
 import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume';
+import { Mat4 } from 'mol-math/linear-algebra';
+import { setTransform } from 'mol-geo/geometry/transform-data';
 
 export interface  ComplexVisual<P extends StructureParams> extends Visual<Structure, P> { }
 
@@ -198,6 +200,9 @@ export function ComplexVisual<P extends ComplexParams>(builder: ComplexVisualGeo
         setPickable(value: boolean) {
             if (renderObject) renderObject.state.pickable = value
         },
+        setTransform(value: Mat4) {
+            if (renderObject) setTransform(value, renderObject.values)
+        },
         destroy() {
             // TODO
             renderObject = undefined

+ 1 - 0
src/mol-repr/structure/units-representation.ts

@@ -164,6 +164,7 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R
     function setState(state: Partial<Representation.State>) {
         if (state.visible !== undefined) visuals.forEach(({ visual }) => visual.setVisibility(state.visible!))
         if (state.pickable !== undefined) visuals.forEach(({ visual }) => visual.setPickable(state.pickable!))
+        if (state.transform !== undefined) visuals.forEach(({ visual }) => visual.setTransform(state.transform!))
 
         Representation.updateState(_state, state)
     }

+ 5 - 0
src/mol-repr/structure/units-visual.ts

@@ -30,6 +30,8 @@ import { ColorTheme } from 'mol-theme/color';
 import { SizeTheme } from 'mol-theme/size';
 import { UnitsParams } from './units-representation';
 import { RenderableState } from 'mol-gl/renderable';
+import { Mat4 } from 'mol-math/linear-algebra';
+import { setTransform } from 'mol-geo/geometry/transform-data';
 
 export type StructureGroup = { structure: Structure, group: Unit.SymmetryGroup }
 
@@ -242,6 +244,9 @@ export function UnitsVisual<P extends UnitsParams>(builder: UnitsVisualGeometryB
         setPickable(value: boolean) {
             if (renderObject) renderObject.state.pickable = value
         },
+        setTransform(value: Mat4) {
+            if (renderObject) setTransform(value, renderObject.values)
+        },
         destroy() {
             // TODO
             renderObject = undefined

+ 5 - 0
src/mol-repr/volume/representation.ts

@@ -22,6 +22,8 @@ import { ValueCell } from 'mol-util';
 import { Theme, createEmptyTheme } from 'mol-theme/theme';
 import { Subject } from 'rxjs';
 import { RenderableState } from 'mol-gl/renderable';
+import { Mat4 } from 'mol-math/linear-algebra';
+import { setTransform } from 'mol-geo/geometry/transform-data';
 
 export interface VolumeVisual<P extends VolumeParams> extends Visual<VolumeData, P> { }
 
@@ -128,6 +130,9 @@ export function VolumeVisual<P extends VolumeParams>(builder: VolumeVisualGeomet
         setPickable(value: boolean) {
             if (renderObject) renderObject.state.pickable = value
         },
+        setTransform(value: Mat4) {
+            if (renderObject) setTransform(value, renderObject.values)
+        },
         destroy() {
             // TODO
             renderObject = undefined