Browse Source

added pyramide primitive

Alexander Rose 6 years ago
parent
commit
9868feafd9

+ 3 - 4
src/mol-geo/primitive/prism.ts

@@ -8,6 +8,7 @@ import { Vec3 } from 'mol-math/linear-algebra'
 import { Primitive, PrimitiveBuilder } from './primitive';
 import { polygon } from './polygon'
 
+const on = Vec3.create(0, 0, -0.5), op = Vec3.create(0, 0, 0.5)
 const a = Vec3.zero(), b = Vec3.zero(), c = Vec3.zero(), d = Vec3.zero()
 
 /**
@@ -58,12 +59,10 @@ export function Prism(points: ArrayLike<number>): Primitive {
             const ni = (i + 1) % sideCount
             Vec3.set(a, points[i * 2], points[i * 2 + 1], -0.5)
             Vec3.set(b, points[ni * 2], points[ni * 2 + 1], -0.5)
-            Vec3.set(c, 0, 0, -0.5)
-            builder.add(a, b, c)
+            builder.add(a, b, on)
             Vec3.set(a, points[i * 2], points[i * 2 + 1], 0.5)
             Vec3.set(b, points[ni * 2], points[ni * 2 + 1], 0.5)
-            Vec3.set(c, 0, 0, 0.5)
-            builder.add(c, b, a)
+            builder.add(op, b, a)
         }
     }
 

+ 60 - 0
src/mol-geo/primitive/pyramid.ts

@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Vec3 } from 'mol-math/linear-algebra'
+import { Primitive, PrimitiveBuilder } from './primitive';
+import { polygon } from './polygon'
+
+const on = Vec3.create(0, 0, -0.5), op = Vec3.create(0, 0, 0.5)
+const a = Vec3.zero(), b = Vec3.zero(), c = Vec3.zero(), d = Vec3.zero()
+
+/**
+ * Create a pyramide with a poligonal base
+ */
+export function Pyramide(points: ArrayLike<number>): Primitive {
+    const sideCount = points.length / 2
+    const baseCount = sideCount === 3 ? 1 : sideCount === 4 ? 2 : sideCount
+    const count = 2 * baseCount + 2 * sideCount
+    const builder = PrimitiveBuilder(count)
+
+    // create sides
+    for (let i = 0; i < sideCount; ++i) {
+        const ni = (i + 1) % sideCount
+        Vec3.set(a, points[i * 2], points[i * 2 + 1], -0.5)
+        Vec3.set(b, points[ni * 2], points[ni * 2 + 1], -0.5)
+        builder.add(a, b, op)
+    }
+
+    // create base
+    if (sideCount === 3) {
+        Vec3.set(a, points[0], points[1], -0.5)
+        Vec3.set(b, points[2], points[3], -0.5)
+        Vec3.set(c, points[4], points[5], -0.5)
+        builder.add(a, b, c)
+    } else if (sideCount === 4) {
+        Vec3.set(a, points[0], points[1], -0.5)
+        Vec3.set(b, points[2], points[3], -0.5)
+        Vec3.set(c, points[4], points[5], -0.5)
+        Vec3.set(d, points[6], points[7], -0.5)
+        builder.add(a, b, c)
+        builder.add(c, d, a)
+    } else {
+        for (let i = 0; i < sideCount; ++i) {
+            const ni = (i + 1) % sideCount
+            Vec3.set(a, points[i * 2], points[i * 2 + 1], -0.5)
+            Vec3.set(b, points[ni * 2], points[ni * 2 + 1], -0.5)
+            builder.add(a, b, on)
+        }
+    }
+
+    return builder.getPrimitive()
+}
+
+let octagonalPyramide: Primitive
+export function OctagonalPyramide() {
+    if (!octagonalPyramide) octagonalPyramide = Pyramide(polygon(8, true))
+    return octagonalPyramide
+}

+ 6 - 9
src/mol-geo/representation/structure/visual/carbohydrate-symbol-mesh.ts

@@ -28,8 +28,6 @@ const t = Mat4.identity()
 const sVec = Vec3.zero()
 const p = Vec3.zero()
 const pd = Vec3.zero()
-const p1 = Vec3.zero()
-const p2 = Vec3.zero()
 
 async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Structure, mesh?: Mesh) {
     const builder = MeshBuilder.create(256, 128, mesh)
@@ -44,7 +42,6 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru
 
     const side = 1.75 * 2 * 0.806; // 0.806 == Math.cos(Math.PI / 4)
     const radius = 1.75
-    const coneParams = { radiusTop: radius, radiusBottom: 0.0, topCap: true }
 
     const linkParams = { radiusTop: 0.4, radiusBottom: 0.4 }
 
@@ -71,15 +68,15 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru
                 builder.addBox(t)
                 break;
             case SaccharideShapes.FilledCone:
-                Vec3.scaleAndSub(p1, cGeo.center, cGeo.direction, radius)
-                Vec3.scaleAndAdd(p2, cGeo.center, cGeo.direction, radius)
-                builder.addCylinder(p1, p2, 1, coneParams)
+                centerAlign(cGeo.center, cGeo.normal, cGeo.direction)
+                Mat4.scaleUniformly(t, t, side * 1.2)
+                builder.addOctagonalPyramid(t)
                 break
             case SaccharideShapes.DevidedCone:
                 // TODO split
-                Vec3.scaleAndSub(p1, cGeo.center, cGeo.direction, radius)
-                Vec3.scaleAndAdd(p2, cGeo.center, cGeo.direction, radius)
-                builder.addCylinder(p1, p2, 1, coneParams)
+                centerAlign(cGeo.center, cGeo.normal, cGeo.direction)
+                Mat4.scaleUniformly(t, t, side * 1.2)
+                builder.addOctagonalPyramid(t)
                 break
             case SaccharideShapes.FlatBox:
                 centerAlign(cGeo.center, cGeo.normal, cGeo.direction)

+ 6 - 0
src/mol-geo/shape/mesh-builder.ts

@@ -19,6 +19,7 @@ import { StarProps, Star } from '../primitive/star';
 import { Octahedron } from '../primitive/octahedron';
 import { Primitive } from '../primitive/primitive';
 import { Wedge, Box, DiamondPrism, PentagonalPrism, HexagonalPrism } from '../primitive/prism';
+import { OctagonalPyramide } from '../primitive/pyramid';
 
 export interface MeshBuilderState {
     vertices: ChunkedArray<number, 3>
@@ -34,6 +35,7 @@ export interface MeshBuilder {
     addDiamondPrism(t: Mat4): void
     addPentagonalPrism(t: Mat4): void
     addHexagonalPrism(t: Mat4): void
+    addOctagonalPyramid(t: Mat4): void
     addStar(t: Mat4, props?: StarProps): void
     addOctahedron(t: Mat4): void
     addCylinder(start: Vec3, end: Vec3, lengthScale: number, props: CylinderProps): void
@@ -158,6 +160,10 @@ export namespace MeshBuilder {
                 const { vertices, normals, indices } = HexagonalPrism()
                 add(t, vertices, normals, indices)
             },
+            addOctagonalPyramid: (t: Mat4) => {
+                const { vertices, normals, indices } = OctagonalPyramide()
+                add(t, vertices, normals, indices)
+            },
             addStar: (t: Mat4, props?: StarProps) => {
                 const { vertices, normals, indices } = Star(props)
                 add(t, vertices, normals, indices)