diff --git a/src/geometries/BoxGeometry.js b/src/geometries/BoxGeometry.ts similarity index 66% rename from src/geometries/BoxGeometry.js rename to src/geometries/BoxGeometry.ts index f6b6c6e..e47f9c7 100644 --- a/src/geometries/BoxGeometry.js +++ b/src/geometries/BoxGeometry.ts @@ -1,5 +1,5 @@ -import { geometryComponent } from './Geometry.js'; -import { BoxGeometry } from 'three'; +import { geometryComponent } from './Geometry.js' +import { BoxGeometry } from 'three' export const props = { size: Number, @@ -9,14 +9,14 @@ export const props = { widthSegments: { type: Number, default: 1 }, heightSegments: { type: Number, default: 1 }, depthSegments: { type: Number, default: 1 }, -}; +} -export function createGeometry(comp) { +export function createGeometry(comp: any): BoxGeometry { if (comp.size) { - return new BoxGeometry(comp.size, comp.size, comp.size, comp.widthSegments, comp.heightSegments, comp.depthSegments); + return new BoxGeometry(comp.size, comp.size, comp.size, comp.widthSegments, comp.heightSegments, comp.depthSegments) } else { - return new BoxGeometry(comp.width, comp.height, comp.depth, comp.widthSegments, comp.heightSegments, comp.depthSegments); + return new BoxGeometry(comp.width, comp.height, comp.depth, comp.widthSegments, comp.heightSegments, comp.depthSegments) } -}; +} -export default geometryComponent('BoxGeometry', props, createGeometry); +export default geometryComponent('BoxGeometry', props, createGeometry) diff --git a/src/geometries/CircleGeometry.js b/src/geometries/CircleGeometry.ts similarity index 63% rename from src/geometries/CircleGeometry.js rename to src/geometries/CircleGeometry.ts index 7b1071a..6ec0114 100644 --- a/src/geometries/CircleGeometry.js +++ b/src/geometries/CircleGeometry.ts @@ -1,15 +1,15 @@ -import { geometryComponent } from './Geometry.js'; -import { CircleGeometry } from 'three'; +import { geometryComponent } from './Geometry.js' +import { CircleGeometry } from 'three' export const props = { radius: { type: Number, default: 1 }, segments: { type: Number, default: 8 }, thetaStart: { type: Number, default: 0 }, thetaLength: { type: Number, default: Math.PI * 2 }, -}; +} -export function createGeometry(comp) { - return new CircleGeometry(comp.radius, comp.segments, comp.thetaStart, comp.thetaLength); -}; +export function createGeometry(comp: any): CircleGeometry { + return new CircleGeometry(comp.radius, comp.segments, comp.thetaStart, comp.thetaLength) +} -export default geometryComponent('CircleGeometry', props, createGeometry); +export default geometryComponent('CircleGeometry', props, createGeometry) diff --git a/src/geometries/ConeGeometry.js b/src/geometries/ConeGeometry.ts similarity index 75% rename from src/geometries/ConeGeometry.js rename to src/geometries/ConeGeometry.ts index aa49e9c..d07fd20 100644 --- a/src/geometries/ConeGeometry.js +++ b/src/geometries/ConeGeometry.ts @@ -1,5 +1,5 @@ -import { geometryComponent } from './Geometry.js'; -import { ConeGeometry } from 'three'; +import { geometryComponent } from './Geometry.js' +import { ConeGeometry } from 'three' export const props = { radius: { type: Number, default: 1 }, @@ -9,10 +9,10 @@ export const props = { openEnded: { type: Boolean, default: false }, thetaStart: { type: Number, default: 0 }, thetaLength: { type: Number, default: Math.PI * 2 }, -}; +} -export function createGeometry(comp) { - return new ConeGeometry(comp.radius, comp.height, comp.radialSegments, comp.heightSegments, comp.openEnded, comp.thetaStart, comp.thetaLength); -}; +export function createGeometry(comp: any): ConeGeometry { + return new ConeGeometry(comp.radius, comp.height, comp.radialSegments, comp.heightSegments, comp.openEnded, comp.thetaStart, comp.thetaLength) +} -export default geometryComponent('ConeGeometry', props, createGeometry); +export default geometryComponent('ConeGeometry', props, createGeometry) diff --git a/src/geometries/CylinderGeometry.js b/src/geometries/CylinderGeometry.ts similarity index 73% rename from src/geometries/CylinderGeometry.js rename to src/geometries/CylinderGeometry.ts index b411897..c84b531 100644 --- a/src/geometries/CylinderGeometry.js +++ b/src/geometries/CylinderGeometry.ts @@ -1,5 +1,5 @@ -import { geometryComponent } from './Geometry.js'; -import { CylinderGeometry } from 'three'; +import { geometryComponent } from './Geometry.js' +import { CylinderGeometry } from 'three' export const props = { radiusTop: { type: Number, default: 1 }, @@ -10,10 +10,10 @@ export const props = { openEnded: { type: Boolean, default: false }, thetaStart: { type: Number, default: 0 }, thetaLength: { type: Number, default: Math.PI * 2 }, -}; +} -export function createGeometry(comp) { - return new CylinderGeometry(comp.radiusTop, comp.radiusBottom, comp.height, comp.radialSegments, comp.heightSegments, comp.openEnded, comp.thetaStart, comp.thetaLength); -}; +export function createGeometry(comp: any): CylinderGeometry { + return new CylinderGeometry(comp.radiusTop, comp.radiusBottom, comp.height, comp.radialSegments, comp.heightSegments, comp.openEnded, comp.thetaStart, comp.thetaLength) +} -export default geometryComponent('CylinderGeometry', props, createGeometry); +export default geometryComponent('CylinderGeometry', props, createGeometry) diff --git a/src/geometries/DodecahedronGeometry.js b/src/geometries/DodecahedronGeometry.js deleted file mode 100644 index 8034afc..0000000 --- a/src/geometries/DodecahedronGeometry.js +++ /dev/null @@ -1,13 +0,0 @@ -import { geometryComponent } from './Geometry.js'; -import { DodecahedronGeometry } from 'three'; - -export const props = { - radius: { type: Number, default: 1 }, - detail: { type: Number, default: 0 }, -}; - -export function createGeometry(comp) { - return new DodecahedronGeometry(comp.radius, comp.detail); -}; - -export default geometryComponent('DodecahedronGeometry', props, createGeometry); diff --git a/src/geometries/DodecahedronGeometry.ts b/src/geometries/DodecahedronGeometry.ts new file mode 100644 index 0000000..5f8b663 --- /dev/null +++ b/src/geometries/DodecahedronGeometry.ts @@ -0,0 +1,13 @@ +import { geometryComponent } from './Geometry.js' +import { DodecahedronGeometry } from 'three' + +export const props = { + radius: { type: Number, default: 1 }, + detail: { type: Number, default: 0 }, +} + +export function createGeometry(comp: any): DodecahedronGeometry { + return new DodecahedronGeometry(comp.radius, comp.detail) +} + +export default geometryComponent('DodecahedronGeometry', props, createGeometry) diff --git a/src/geometries/Geometry.js b/src/geometries/Geometry.js deleted file mode 100644 index d8d8777..0000000 --- a/src/geometries/Geometry.js +++ /dev/null @@ -1,64 +0,0 @@ -import { defineComponent, watch } from 'vue'; - -const Geometry = defineComponent({ - inject: ['mesh'], - props: { - rotateX: Number, - rotateY: Number, - rotateZ: Number, - }, - created() { - if (!this.mesh) { - console.error('Missing parent Mesh'); - } - - this.watchProps = []; - Object.entries(this.$props).forEach(e => this.watchProps.push(e[0])); - - this.createGeometry(); - this.rotateGeometry(); - this.mesh.setGeometry(this.geometry); - - this.addWatchers(); - }, - unmounted() { - this.geometry.dispose(); - }, - methods: { - addWatchers() { - this.watchProps.forEach(prop => { - watch(() => this[prop], () => { - this.refreshGeometry(); - }); - }); - }, - rotateGeometry() { - if (this.rotateX) this.geometry.rotateX(this.rotateX); - if (this.rotateY) this.geometry.rotateY(this.rotateY); - if (this.rotateZ) this.geometry.rotateZ(this.rotateZ); - }, - refreshGeometry() { - const oldGeo = this.geometry; - this.createGeometry(); - this.rotateGeometry(); - this.mesh.setGeometry(this.geometry); - oldGeo.dispose(); - }, - }, - render() { return []; }, -}); - -export default Geometry; - -export function geometryComponent(name, props, createGeometry) { - return defineComponent({ - name, - extends: Geometry, - props, - methods: { - createGeometry() { - this.geometry = createGeometry(this); - }, - }, - }); -}; diff --git a/src/geometries/Geometry.ts b/src/geometries/Geometry.ts new file mode 100644 index 0000000..3171298 --- /dev/null +++ b/src/geometries/Geometry.ts @@ -0,0 +1,64 @@ +import { defineComponent, watch } from 'vue' + +const Geometry = defineComponent({ + inject: ['mesh'], + props: { + rotateX: Number, + rotateY: Number, + rotateZ: Number, + }, + created() { + if (!this.mesh) { + console.error('Missing parent Mesh') + } + + this.watchProps = [] + Object.entries(this.$props).forEach(e => this.watchProps.push(e[0])) + + this.createGeometry() + this.rotateGeometry() + this.mesh.setGeometry(this.geometry) + + this.addWatchers() + }, + unmounted() { + this.geometry.dispose() + }, + methods: { + addWatchers() { + this.watchProps.forEach(prop => { + watch(() => this[prop], () => { + this.refreshGeometry() + }) + }) + }, + rotateGeometry() { + if (this.rotateX) this.geometry.rotateX(this.rotateX) + if (this.rotateY) this.geometry.rotateY(this.rotateY) + if (this.rotateZ) this.geometry.rotateZ(this.rotateZ) + }, + refreshGeometry() { + const oldGeo = this.geometry + this.createGeometry() + this.rotateGeometry() + this.mesh.setGeometry(this.geometry) + oldGeo.dispose() + }, + }, + render() { return []; }, +}) + +export default Geometry + +export function geometryComponent(name, props, createGeometry) { + return defineComponent({ + name, + extends: Geometry, + props, + methods: { + createGeometry() { + this.geometry = createGeometry(this) + }, + }, + }) +} diff --git a/src/geometries/IcosahedronGeometry.js b/src/geometries/IcosahedronGeometry.js deleted file mode 100644 index 69156bd..0000000 --- a/src/geometries/IcosahedronGeometry.js +++ /dev/null @@ -1,13 +0,0 @@ -import { geometryComponent } from './Geometry.js'; -import { IcosahedronGeometry } from 'three'; - -export const props = { - radius: { type: Number, default: 1 }, - detail: { type: Number, default: 0 }, -}; - -export function createGeometry(comp) { - return new IcosahedronGeometry(comp.radius, comp.detail); -}; - -export default geometryComponent('IcosahedronGeometry', props, createGeometry); diff --git a/src/geometries/IcosahedronGeometry.ts b/src/geometries/IcosahedronGeometry.ts new file mode 100644 index 0000000..65ca668 --- /dev/null +++ b/src/geometries/IcosahedronGeometry.ts @@ -0,0 +1,13 @@ +import { geometryComponent } from './Geometry.js' +import { IcosahedronGeometry } from 'three' + +export const props = { + radius: { type: Number, default: 1 }, + detail: { type: Number, default: 0 }, +} + +export function createGeometry(comp: any): IcosahedronGeometry { + return new IcosahedronGeometry(comp.radius, comp.detail) +} + +export default geometryComponent('IcosahedronGeometry', props, createGeometry) diff --git a/src/geometries/LatheGeometry.js b/src/geometries/LatheGeometry.ts similarity index 62% rename from src/geometries/LatheGeometry.js rename to src/geometries/LatheGeometry.ts index b041cf1..c0b7fbe 100644 --- a/src/geometries/LatheGeometry.js +++ b/src/geometries/LatheGeometry.ts @@ -1,15 +1,15 @@ -import { geometryComponent } from './Geometry.js'; -import { LatheGeometry } from 'three'; +import { geometryComponent } from './Geometry.js' +import { LatheGeometry } from 'three' export const props = { points: Array, segments: { type: Number, default: 12 }, phiStart: { type: Number, default: 0 }, phiLength: { type: Number, default: Math.PI * 2 }, -}; +} -export function createGeometry(comp) { - return new LatheGeometry(comp.points, comp.segments, comp.phiStart, comp.phiLength); -}; +export function createGeometry(comp: any): LatheGeometry { + return new LatheGeometry(comp.points, comp.segments, comp.phiStart, comp.phiLength) +} -export default geometryComponent('LatheGeometry', props, createGeometry); +export default geometryComponent('LatheGeometry', props, createGeometry) diff --git a/src/geometries/OctahedronGeometry.js b/src/geometries/OctahedronGeometry.js deleted file mode 100644 index 077b904..0000000 --- a/src/geometries/OctahedronGeometry.js +++ /dev/null @@ -1,13 +0,0 @@ -import { geometryComponent } from './Geometry.js'; -import { OctahedronGeometry } from 'three'; - -export const props = { - radius: { type: Number, default: 1 }, - detail: { type: Number, default: 0 }, -}; - -export function createGeometry(comp) { - return new OctahedronGeometry(comp.radius, comp.detail); -}; - -export default geometryComponent('OctahedronGeometry', props, createGeometry); diff --git a/src/geometries/OctahedronGeometry.ts b/src/geometries/OctahedronGeometry.ts new file mode 100644 index 0000000..5b151c6 --- /dev/null +++ b/src/geometries/OctahedronGeometry.ts @@ -0,0 +1,13 @@ +import { geometryComponent } from './Geometry.js' +import { OctahedronGeometry } from 'three' + +export const props = { + radius: { type: Number, default: 1 }, + detail: { type: Number, default: 0 }, +} + +export function createGeometry(comp: any): OctahedronGeometry { + return new OctahedronGeometry(comp.radius, comp.detail) +} + +export default geometryComponent('OctahedronGeometry', props, createGeometry) diff --git a/src/geometries/PlaneGeometry.js b/src/geometries/PlaneGeometry.ts similarity index 63% rename from src/geometries/PlaneGeometry.js rename to src/geometries/PlaneGeometry.ts index 7a78818..18f0fb4 100644 --- a/src/geometries/PlaneGeometry.js +++ b/src/geometries/PlaneGeometry.ts @@ -1,15 +1,15 @@ -import { geometryComponent } from './Geometry.js'; -import { PlaneGeometry } from 'three'; +import { geometryComponent } from './Geometry.js' +import { PlaneGeometry } from 'three' export const props = { width: { type: Number, default: 1 }, height: { type: Number, default: 1 }, widthSegments: { type: Number, default: 1 }, heightSegments: { type: Number, default: 1 }, -}; +} -export function createGeometry(comp) { - return new PlaneGeometry(comp.width, comp.height, comp.widthSegments, comp.heightSegments); -}; +export function createGeometry(comp: any): PlaneGeometry { + return new PlaneGeometry(comp.width, comp.height, comp.widthSegments, comp.heightSegments) +} -export default geometryComponent('PlaneGeometry', props, createGeometry); +export default geometryComponent('PlaneGeometry', props, createGeometry) diff --git a/src/geometries/PolyhedronGeometry.js b/src/geometries/PolyhedronGeometry.ts similarity index 57% rename from src/geometries/PolyhedronGeometry.js rename to src/geometries/PolyhedronGeometry.ts index b030139..aefbfa0 100644 --- a/src/geometries/PolyhedronGeometry.js +++ b/src/geometries/PolyhedronGeometry.ts @@ -1,15 +1,15 @@ -import { geometryComponent } from './Geometry.js'; -import { PolyhedronGeometry } from 'three'; +import { geometryComponent } from './Geometry.js' +import { PolyhedronGeometry } from 'three' export const props = { vertices: Array, indices: Array, radius: { type: Number, default: 1 }, detail: { type: Number, default: 0 }, -}; +} -export function createGeometry(comp) { - return new PolyhedronGeometry(comp.vertices, comp.indices, comp.radius, comp.detail); -}; +export function createGeometry(comp: any): PolyhedronGeometry { + return new PolyhedronGeometry(comp.vertices, comp.indices, comp.radius, comp.detail) +} -export default geometryComponent('PolyhedronGeometry', props, createGeometry); +export default geometryComponent('PolyhedronGeometry', props, createGeometry) diff --git a/src/geometries/RingGeometry.js b/src/geometries/RingGeometry.ts similarity index 75% rename from src/geometries/RingGeometry.js rename to src/geometries/RingGeometry.ts index 5eb7b72..994834b 100644 --- a/src/geometries/RingGeometry.js +++ b/src/geometries/RingGeometry.ts @@ -1,5 +1,5 @@ -import { geometryComponent } from './Geometry.js'; -import { RingGeometry } from 'three'; +import { geometryComponent } from './Geometry.js' +import { RingGeometry } from 'three' export const props = { innerRadius: { type: Number, default: 0.5 }, @@ -8,10 +8,10 @@ export const props = { phiSegments: { type: Number, default: 1 }, thetaStart: { type: Number, default: 0 }, thetaLength: { type: Number, default: Math.PI * 2 }, -}; +} -export function createGeometry(comp) { - return new RingGeometry(comp.innerRadius, comp.outerRadius, comp.thetaSegments, comp.phiSegments, comp.thetaStart, comp.thetaLength); -}; +export function createGeometry(comp: any): RingGeometry { + return new RingGeometry(comp.innerRadius, comp.outerRadius, comp.thetaSegments, comp.phiSegments, comp.thetaStart, comp.thetaLength) +} -export default geometryComponent('RingGeometry', props, createGeometry); +export default geometryComponent('RingGeometry', props, createGeometry) diff --git a/src/geometries/SphereGeometry.js b/src/geometries/SphereGeometry.ts similarity index 61% rename from src/geometries/SphereGeometry.js rename to src/geometries/SphereGeometry.ts index 5293877..2b302ea 100644 --- a/src/geometries/SphereGeometry.js +++ b/src/geometries/SphereGeometry.ts @@ -1,14 +1,14 @@ -import { geometryComponent } from './Geometry.js'; -import { SphereGeometry } from 'three'; +import { geometryComponent } from './Geometry.js' +import { SphereGeometry } from 'three' export const props = { radius: { type: Number, default: 1 }, widthSegments: { type: Number, default: 12 }, heightSegments: { type: Number, default: 12 }, -}; +} -export function createGeometry(comp) { - return new SphereGeometry(comp.radius, comp.widthSegments, comp.heightSegments); -}; +export function createGeometry(comp: any): SphereGeometry { + return new SphereGeometry(comp.radius, comp.widthSegments, comp.heightSegments) +} -export default geometryComponent('SphereGeometry', props, createGeometry); +export default geometryComponent('SphereGeometry', props, createGeometry) diff --git a/src/geometries/TetrahedronGeometry.js b/src/geometries/TetrahedronGeometry.js deleted file mode 100644 index 733ff5c..0000000 --- a/src/geometries/TetrahedronGeometry.js +++ /dev/null @@ -1,13 +0,0 @@ -import { geometryComponent } from './Geometry.js'; -import { TetrahedronGeometry } from 'three'; - -export const props = { - radius: { type: Number, default: 1 }, - detail: { type: Number, default: 0 }, -}; - -export function createGeometry(comp) { - return new TetrahedronGeometry(comp.radius, comp.detail); -}; - -export default geometryComponent('TetrahedronGeometry', props, createGeometry); diff --git a/src/geometries/TetrahedronGeometry.ts b/src/geometries/TetrahedronGeometry.ts new file mode 100644 index 0000000..397e8a8 --- /dev/null +++ b/src/geometries/TetrahedronGeometry.ts @@ -0,0 +1,13 @@ +import { geometryComponent } from './Geometry.js' +import { TetrahedronGeometry } from 'three' + +export const props = { + radius: { type: Number, default: 1 }, + detail: { type: Number, default: 0 }, +} + +export function createGeometry(comp: any): TetrahedronGeometry { + return new TetrahedronGeometry(comp.radius, comp.detail) +} + +export default geometryComponent('TetrahedronGeometry', props, createGeometry) diff --git a/src/geometries/TorusGeometry.js b/src/geometries/TorusGeometry.ts similarity index 65% rename from src/geometries/TorusGeometry.js rename to src/geometries/TorusGeometry.ts index 6cd501d..644488e 100644 --- a/src/geometries/TorusGeometry.js +++ b/src/geometries/TorusGeometry.ts @@ -1,5 +1,5 @@ -import { geometryComponent } from './Geometry.js'; -import { TorusGeometry } from 'three'; +import { geometryComponent } from './Geometry.js' +import { TorusGeometry } from 'three' export const props = { radius: { type: Number, default: 1 }, @@ -7,10 +7,10 @@ export const props = { radialSegments: { type: Number, default: 8 }, tubularSegments: { type: Number, default: 6 }, arc: { type: Number, default: Math.PI * 2 }, -}; +} -export function createGeometry(comp) { - return new TorusGeometry(comp.radius, comp.tube, comp.radialSegments, comp.tubularSegments, comp.arc); -}; +export function createGeometry(comp: any): TorusGeometry { + return new TorusGeometry(comp.radius, comp.tube, comp.radialSegments, comp.tubularSegments, comp.arc) +} -export default geometryComponent('TorusGeometry', props, createGeometry); +export default geometryComponent('TorusGeometry', props, createGeometry) diff --git a/src/geometries/TorusKnotGeometry.js b/src/geometries/TorusKnotGeometry.ts similarity index 64% rename from src/geometries/TorusKnotGeometry.js rename to src/geometries/TorusKnotGeometry.ts index f02ed14..234e32c 100644 --- a/src/geometries/TorusKnotGeometry.js +++ b/src/geometries/TorusKnotGeometry.ts @@ -1,5 +1,5 @@ -import { geometryComponent } from './Geometry.js'; -import { TorusKnotGeometry } from 'three'; +import { geometryComponent } from './Geometry.js' +import { TorusKnotGeometry } from 'three' export const props = { radius: { type: Number, default: 1 }, @@ -8,10 +8,10 @@ export const props = { radialSegments: { type: Number, default: 8 }, p: { type: Number, default: 2 }, q: { type: Number, default: 3 }, -}; +} -export function createGeometry(comp) { - return new TorusKnotGeometry(comp.radius, comp.tube, comp.tubularSegments, comp.radialSegments, comp.p, comp.q); -}; +export function createGeometry(comp: any): TorusKnotGeometry { + return new TorusKnotGeometry(comp.radius, comp.tube, comp.tubularSegments, comp.radialSegments, comp.p, comp.q) +} -export default geometryComponent('TorusKnotGeometry', props, createGeometry); +export default geometryComponent('TorusKnotGeometry', props, createGeometry) diff --git a/src/geometries/TubeGeometry.js b/src/geometries/TubeGeometry.js deleted file mode 100644 index 2c36a69..0000000 --- a/src/geometries/TubeGeometry.js +++ /dev/null @@ -1,83 +0,0 @@ -import { defineComponent } from 'vue'; -import { CatmullRomCurve3, Curve, TubeGeometry, Vector3 } from 'three'; -import Geometry from './Geometry.js'; - -export const props = { - points: Array, - path: Curve, - tubularSegments: { type: Number, default: 64 }, - radius: { type: Number, default: 1 }, - radialSegments: { type: Number, default: 8 }, - closed: { type: Boolean, default: false }, -}; - -export function createGeometry(comp) { - let curve; - if (comp.points) { - curve = new CatmullRomCurve3(comp.points); - } else if (comp.path) { - curve = comp.path; - } else { - console.error('Missing path curve or points.'); - } - return new TubeGeometry(curve, comp.tubularSegments, comp.radius, comp.radiusSegments, comp.closed); -}; - -export default defineComponent({ - extends: Geometry, - props, - methods: { - createGeometry() { - this.geometry = createGeometry(this); - }, - // update points (without using prop, faster) - updatePoints(points) { - updateTubeGeometryPoints(this.geometry, points); - }, - }, -}); - -export function updateTubeGeometryPoints(tube, points) { - const curve = new CatmullRomCurve3(points); - const { radialSegments, radius, tubularSegments, closed } = tube.parameters; - const frames = curve.computeFrenetFrames(tubularSegments, closed); - tube.tangents = frames.tangents; - tube.normals = frames.normals; - tube.binormals = frames.binormals; - tube.parameters.path = curve; - - const pArray = tube.attributes.position.array; - const nArray = tube.attributes.normal.array; - const normal = new Vector3(); - let P; - - for (let i = 0; i < tubularSegments; i++) { - updateSegment(i); - } - updateSegment(tubularSegments); - - tube.attributes.position.needsUpdate = true; - tube.attributes.normal.needsUpdate = true; - - function updateSegment(i) { - P = curve.getPointAt(i / tubularSegments, P); - const N = frames.normals[i]; - const B = frames.binormals[i]; - for (let j = 0; j <= radialSegments; j++) { - const v = j / radialSegments * Math.PI * 2; - const sin = Math.sin(v); - const cos = -Math.cos(v); - normal.x = (cos * N.x + sin * B.x); - normal.y = (cos * N.y + sin * B.y); - normal.z = (cos * N.z + sin * B.z); - normal.normalize(); - const index = (i * (radialSegments + 1) + j) * 3; - nArray[index] = normal.x; - nArray[index + 1] = normal.y; - nArray[index + 2] = normal.z; - pArray[index] = P.x + radius * normal.x; - pArray[index + 1] = P.y + radius * normal.y; - pArray[index + 2] = P.z + radius * normal.z; - } - } -} diff --git a/src/geometries/TubeGeometry.ts b/src/geometries/TubeGeometry.ts new file mode 100644 index 0000000..32ee58b --- /dev/null +++ b/src/geometries/TubeGeometry.ts @@ -0,0 +1,80 @@ +import { defineComponent } from 'vue' +import { CatmullRomCurve3, Curve, TubeGeometry, Vector3 } from 'three' +import Geometry from './Geometry.js' + +export const props = { + points: Array, + path: Curve, + tubularSegments: { type: Number, default: 64 }, + radius: { type: Number, default: 1 }, + radialSegments: { type: Number, default: 8 }, + closed: { type: Boolean, default: false }, +} + +export function createGeometry(comp: any): TubeGeometry { + let curve + if (comp.points) { + curve = new CatmullRomCurve3(comp.points) + } else if (comp.path) { + curve = comp.path + } else { + console.error('Missing path curve or points.') + } + return new TubeGeometry(curve, comp.tubularSegments, comp.radius, comp.radiusSegments, comp.closed) +} + +export default defineComponent({ + extends: Geometry, + props, + methods: { + createGeometry() { + this.geometry = createGeometry(this) + }, + // update points (without using prop, faster) + updatePoints(points: Vector3[]) { + updateTubeGeometryPoints(this.geometry, points) + }, + }, +}) + +export function updateTubeGeometryPoints(tube: TubeGeometry, points: Vector3[]): void { + const curve = new CatmullRomCurve3(points) + const { radialSegments, radius, tubularSegments, closed } = tube.parameters + const frames = curve.computeFrenetFrames(tubularSegments, closed) + tube.tangents = frames.tangents + tube.normals = frames.normals + tube.binormals = frames.binormals + tube.parameters.path = curve + + const pAttribute = tube.getAttribute('position') + const nAttribute = tube.getAttribute('normal') + + const normal = new Vector3() + let P = new Vector3() + + for (let i = 0; i < tubularSegments; i++) { + updateSegment(i) + } + updateSegment(tubularSegments) + + tube.attributes.position.needsUpdate = true + tube.attributes.normal.needsUpdate = true + + function updateSegment(i: number) { + P = curve.getPointAt(i / tubularSegments, P) + const N = frames.normals[i] + const B = frames.binormals[i] + for (let j = 0; j <= radialSegments; j++) { + const v = j / radialSegments * Math.PI * 2 + const sin = Math.sin(v) + const cos = -Math.cos(v) + normal.x = (cos * N.x + sin * B.x) + normal.y = (cos * N.y + sin * B.y) + normal.z = (cos * N.z + sin * B.z) + normal.normalize() + const index = (i * (radialSegments + 1) + j) * 3 + nAttribute.setXYZ(index, normal.x, normal.y, normal.z) + pAttribute.setXYZ(index, P.x + radius * normal.x, P.y + radius * normal.y, P.z + radius * normal.z) + } + } +} diff --git a/src/geometries/index.js b/src/geometries/index.js index 9fc20d4..646a49b 100644 --- a/src/geometries/index.js +++ b/src/geometries/index.js @@ -1,16 +1,16 @@ -export { default as BoxGeometry } from './BoxGeometry.js'; -export { default as CircleGeometry } from './CircleGeometry.js'; -export { default as ConeGeometry } from './ConeGeometry.js'; -export { default as CylinderGeometry } from './CylinderGeometry.js'; -export { default as DodecahedronGeometry } from './DodecahedronGeometry.js'; -export { default as IcosahedronGeometry } from './IcosahedronGeometry.js'; -export { default as LatheGeometry } from './LatheGeometry.js'; -export { default as OctahedronGeometry } from './OctahedronGeometry.js'; -export { default as PlaneGeometry } from './PlaneGeometry.js'; -export { default as PolyhedronGeometry } from './PolyhedronGeometry.js'; -export { default as RingGeometry } from './RingGeometry.js'; -export { default as SphereGeometry } from './SphereGeometry.js'; -export { default as TetrahedronGeometry } from './TetrahedronGeometry.js'; -export { default as TorusGeometry } from './TorusGeometry.js'; -export { default as TorusKnotGeometry } from './TorusKnotGeometry.js'; -export { default as TubeGeometry } from './TubeGeometry.js'; +export { default as BoxGeometry } from './BoxGeometry' +export { default as CircleGeometry } from './CircleGeometry' +export { default as ConeGeometry } from './ConeGeometry' +export { default as CylinderGeometry } from './CylinderGeometry' +export { default as DodecahedronGeometry } from './DodecahedronGeometry' +export { default as IcosahedronGeometry } from './IcosahedronGeometry' +export { default as LatheGeometry } from './LatheGeometry' +export { default as OctahedronGeometry } from './OctahedronGeometry' +export { default as PlaneGeometry } from './PlaneGeometry' +export { default as PolyhedronGeometry } from './PolyhedronGeometry' +export { default as RingGeometry } from './RingGeometry' +export { default as SphereGeometry } from './SphereGeometry' +export { default as TetrahedronGeometry } from './TetrahedronGeometry' +export { default as TorusGeometry } from './TorusGeometry' +export { default as TorusKnotGeometry } from './TorusKnotGeometry' +export { default as TubeGeometry } from './TubeGeometry' diff --git a/src/geometries/rename.bat b/src/geometries/rename.bat new file mode 100644 index 0000000..e86381c --- /dev/null +++ b/src/geometries/rename.bat @@ -0,0 +1,2 @@ +ren *.js *.ts +pause