فهرست منبع

wip, circle primitive

Alexander Rose 5 سال پیش
والد
کامیت
2a28b5421f
1فایلهای تغییر یافته به همراه91 افزوده شده و 0 حذف شده
  1. 91 0
      src/mol-geo/primitive/circle.ts

+ 91 - 0
src/mol-geo/primitive/circle.ts

@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Primitive } from './primitive';
+import { Cage } from './cage';
+
+export const DefaultCircleProps = {
+    radius: 1,
+    segments: 4,
+    thetaStart: 0,
+    thetaLength: Math.PI * 2
+}
+export type CirclerProps = Partial<typeof DefaultCircleProps>
+
+export function Circle(props?: CirclerProps): Primitive {
+    const { radius, segments, thetaStart, thetaLength } = { ...DefaultCircleProps, ...props }
+
+    const isFull = thetaLength === Math.PI * 2
+    const count = isFull ? segments + 1 : segments + 2
+
+    const vertices = new Float32Array(count * 3)
+    const normals = new Float32Array(count * 3)
+    const indices = new Uint32Array(segments * 3)
+
+    // center
+    vertices[0] = 0; vertices[1] = 0; vertices[2] = 0;
+    normals[0] = 0; normals[1] = 0; normals[2] = 1;
+
+    // vertices & normals
+    for (let s = 0, i = 3; s < segments; ++s, i += 3) {
+        const segment = thetaStart + s / segments * thetaLength;
+
+        vertices[i] = radius * Math.cos(segment)
+        vertices[i + 1] = radius * Math.sin(segment)
+        vertices[i + 2] = 0
+
+        normals[i] = 0; normals[i + 1] = 0; normals[i + 2] = 1;
+    }
+
+    // indices
+    for (let s = 1, i = 0; s <= segments; ++s, i += 3) {
+        indices[i] = s; indices[i + 1] = s + 1; indices[i + 2] = 0;
+    }
+
+    if (isFull) {
+        // indices[i] = s; indices[i + 1] = s + 1; indices[i + 2] = 0;
+    } else {
+        const segment = thetaStart + thetaLength;
+        const i = (segments + 1) * 3
+
+        vertices[i] = radius * Math.cos(segment)
+        vertices[i + 1] = radius * Math.sin(segment)
+        vertices[i + 2] = 0
+
+        normals[i] = 0; normals[i + 1] = 0; normals[i + 2] = 1;
+
+        const j = segments * 3
+        indices[j] = segments + 1
+        indices[j + 1] = segments + 2
+        indices[j + 2] = 0
+    }
+
+    return { vertices, normals, indices }
+}
+
+export function CircleCage(props?: CirclerProps): Cage {
+    const { radius, segments, thetaStart, thetaLength } = { ...DefaultCircleProps, ...props }
+
+    const n = segments * 3
+    const vertices = new Float32Array(n)
+    const edges = new Uint32Array(n)
+
+    for (let s = 0, i = 0; s <= segments; ++s, i += 3) {
+        const segment = thetaStart + s / segments * thetaLength;
+
+        // vertex
+        vertices[i] = radius * Math.cos(segment)
+        vertices[i + 1] = radius * Math.sin(segment)
+        vertices[i + 2] = 0
+    }
+
+    // indices
+    for (let s = 1, i = 0; s <= segments; ++s, i += 3) {
+        edges[0] = s; edges[1] = s + 1;
+    }
+
+    return { vertices, edges }
+}