Skip to content

Commit

Permalink
feat: add hardcoded bezier curves
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-aksamentov committed Feb 28, 2023
1 parent 4f99643 commit 1fd557b
Show file tree
Hide file tree
Showing 24 changed files with 3,727 additions and 37 deletions.
1 change: 1 addition & 0 deletions web/.eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ config/next/lib/EmitFilePlugin.js
infra/lambda-at-edge/basicAuth.js
node_modules
public
src/vendor
styles
tsconfig.json
2 changes: 2 additions & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"bootstrap": "4.5.2",
"bootstrap-icons": "1.10.3",
"classnames": "2.3.2",
"color": "4.2.3",
"core-js": "3.28.0",
"countries-list": "2.6.1",
"country-flag-icons": "1.5.5",
Expand Down Expand Up @@ -138,6 +139,7 @@
"@testing-library/react": "14.0.0",
"@testing-library/user-event": "14.4.3",
"@types/classnames": "2.3.0",
"@types/color": "3.0.3",
"@types/compression": "1.7.2",
"@types/copy-webpack-plugin": "8.0.1",
"@types/express": "4.17.17",
Expand Down
47 changes: 11 additions & 36 deletions web/src/components/Viewer/Renderer.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
import {
AxesHelper,
DoubleSide,
Mesh,
MeshBasicMaterial,
PerspectiveCamera,
Scene,
TorusGeometry,
WebGLRenderer,
} from 'three'
import { AxesHelper, Object3D, PerspectiveCamera, Scene, Vector2, WebGLRenderer } from 'three'
import { Easing, Tween } from '@tweenjs/tween.js'
import { OrbitControls } from 'three-stdlib'
import type { RenderSettings } from 'src/components/Viewer/Scene'
Expand All @@ -16,23 +7,9 @@ import { CameraPreset } from 'src/state/camera.state'
import { FrameCounter, RenderStats } from './gl/FrameCounter'
import { makeCoordinatePlanes } from './gl/makePlane'
import { UserInput } from './gl/UserInput'
import { makeBezierCurves } from './makeBezierCurves'

const CAMERA_POS_Z = 300

export async function initGeometry(mesh?: Mesh) {
const geometry = new TorusGeometry(10, 3, 16, 100)

const material = new MeshBasicMaterial({ color: 'lime', vertexColors: false, side: DoubleSide })
if (!mesh) {
mesh = new Mesh(geometry, material) // eslint-disable-line no-param-reassign
}

// NOTE: Apply default mesh rotation, to make sure the default view is along negative Z axis.
// NOTE: This prevents weird OrbitControls behavior.
mesh.rotation.x = -Math.PI / 2

return mesh
}
const CAMERA_POS_Z = 50

export function getViewportSize(canvas: HTMLCanvasElement) {
if (!canvas.parentElement) {
Expand All @@ -53,8 +30,7 @@ export class Renderer {
private cameraPresetTarget: CameraPreset | undefined
private cameraTween: Tween<CameraPreset> | undefined

private mesh: Mesh | undefined
private material: MeshBasicMaterial | undefined
private objects: Object3D[] = []

private rafHandle: number | undefined
private shouldRender = true
Expand Down Expand Up @@ -99,28 +75,27 @@ export class Renderer {

this.input = new UserInput(canvas)

void this.init() // eslint-disable-line no-void
void this.init(new Vector2(width, height)) // eslint-disable-line no-void
}

public async init() {
this.mesh = await initGeometry(this.mesh)
this.mesh.geometry.computeBoundingSphere()
this.scene.add(this.mesh)

public async init(resolution: Vector2) {
const axesHelper = new AxesHelper(1000)
this.scene.add(axesHelper)

const coordPlanes = makeCoordinatePlanes()
this.scene.add(...coordPlanes)

this.objects = makeBezierCurves(resolution)
this.scene.add(...this.objects)
}

public destroy() {
if (this.rafHandle) {
cancelAnimationFrame(this.rafHandle)
}

this.mesh?.geometry.dispose()
this.material?.dispose()
// this.objects.forEach(object => object.geometry.dispose())
// this.material?.dispose()
this.camera.clear()
this.controls.dispose()
this.scene.clear()
Expand Down
87 changes: 87 additions & 0 deletions web/src/components/Viewer/makeBezierCurves.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { CubicBezierCurve3, Vector2, Vector3 } from 'three'
import { Line2, LineGeometry, LineMaterial } from 'src/vendor/three-fatline/src'
import Color from 'color'

export interface Curve {
color: string
points: [Vector3, Vector3, Vector3, Vector3]
}

const CURVES: Curve[] = [
{
color: '#f00',
points: [
// prettier-ignore
new Vector3(-10, 0, 0),
new Vector3(-5, 15, 0),
new Vector3(20, 15, 0),
new Vector3(10, 0, 0),
],
},
{
color: '#00f',
points: [
// prettier-ignore
new Vector3(-10, 0, 0),
new Vector3(0, -5, 5),
new Vector3(0, -8, 5),
new Vector3(10, 0, 0),
],
},
{
color: '#0f0',
points: [
// prettier-ignore
new Vector3(-10, 0, 0),
new Vector3(0, 0, 2),
new Vector3(0, 2, 0),
new Vector3(10, 0, 0),
],
},
{
color: '#0ff',
points: [
// prettier-ignore
new Vector3(-10, 0, 0),
new Vector3(-15, 5, 2),
new Vector3(-20, 2, 5),
new Vector3(-10, 0, 0),
],
},
{
color: '#ff0',
points: [
// prettier-ignore
new Vector3(10, 0, 0),
new Vector3(20, 5, 2),
new Vector3(15, 2, 5),
new Vector3(10, 0, 0),
],
},
]

export function makeBezierCurve(
bezierPoints: [Vector3, Vector3, Vector3, Vector3],
color: string,
resolution: Vector2,
) {
const points = new CubicBezierCurve3(...bezierPoints).getPoints(50)

const geometry = new LineGeometry()
geometry.setPositions(points.flatMap(({ x, y, z }) => [x, y, z]))

const material = new LineMaterial({
color: new Color(color).rgbNumber(),
linewidth: 10,
resolution,
})

const curve = new Line2(geometry, material)
curve.geometry.computeBoundingSphere()

return curve
}

export function makeBezierCurves(resolution: Vector2) {
return CURVES.map((curve) => makeBezierCurve(curve.points, curve.color, resolution))
}
36 changes: 36 additions & 0 deletions web/src/vendor/three-fatline/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
three-fatline
=============

[![NPM package][npm-img]][npm-url]
[![Build Size][build-size-img]][build-size-url]
[![NPM Downloads][npm-downloads-img]][npm-downloads-url]

A modularized version of [https://github.com/mrdoob/three.js/blob/master/examples/js/lines/](https://github.com/mrdoob/three.js/blob/master/examples/js/lines/).

See the [example](https://vasturiano.github.io/three-fatline/example/fat-lines/) ([source](https://github.com/vasturiano/three-fatline/blob/master/example/fat-lines/index.html))

#### Usage Example:
```js
import { Line2, LineGeometry, LineMaterial } from 'three-fatline';

const geometry = new LineGeometry();
geometry.setPositions([-160, 200, 0, 0, -200, 0, 160, 200, 0]); // [ x1, y1, z1, x2, y2, z2, ... ] format

const material = new LineMaterial({
color: 'red',
linewidth: 10, // px
resolution: new THREE.Vector2(640, 480) // resolution of the viewport
// dashed, dashScale, dashSize, gapSize
});

const myLine = new Line2(geometry, matLine);

myLine.computeLineDistances();
```

[npm-img]: https://img.shields.io/npm/v/three-fatline
[npm-url]: https://npmjs.org/package/three-fatline
[build-size-img]: https://img.shields.io/bundlephobia/minzip/three-fatline
[build-size-url]: https://bundlephobia.com/result?p=three-fatline
[npm-downloads-img]: https://img.shields.io/npm/dt/three-fatline
[npm-downloads-url]: https://www.npmtrends.com/three-fatline
Loading

1 comment on commit 1fd557b

@vercel
Copy link

@vercel vercel bot commented on 1fd557b Feb 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

pangraph – ./

pangraph-git-web-neherlab.vercel.app
pangraph-neherlab.vercel.app
pangraph.vercel.app

Please sign in to comment.