From 5af9f0a9142af54121b58f5fdd95b6bc2c7becb6 Mon Sep 17 00:00:00 2001 From: Chau Tran Date: Tue, 22 Feb 2022 22:54:55 -0600 Subject: [PATCH] docs(storybook): add object clump fork --- .../object-clump/object-clump.component.ts | 214 +++++++++++++++++ .../src/cannon/object-clump/object-clump.mdx | 218 ++++++++++++++++++ .../object-clump/object-clump.stories.ts | 23 ++ .../simple-physics.component.ts | 23 +- 4 files changed, 473 insertions(+), 5 deletions(-) create mode 100644 libs/storybook/src/cannon/object-clump/object-clump.component.ts create mode 100644 libs/storybook/src/cannon/object-clump/object-clump.mdx create mode 100644 libs/storybook/src/cannon/object-clump/object-clump.stories.ts diff --git a/libs/storybook/src/cannon/object-clump/object-clump.component.ts b/libs/storybook/src/cannon/object-clump/object-clump.component.ts new file mode 100644 index 000000000..4d4aeb0d0 --- /dev/null +++ b/libs/storybook/src/cannon/object-clump/object-clump.component.ts @@ -0,0 +1,214 @@ +import { + GetByIndex, + NgtPhysicsModule, + SphereProps, +} from '@angular-three/cannon'; +import { + NgtPhysicSphere, + NgtPhysicSphereModule, +} from '@angular-three/cannon/bodies'; +import { NgtCannonDebugModule } from '@angular-three/cannon/debug'; +import { + NgtAnimationFrameStore, + NgtCoreModule, + NgtStore, + NgtTriplet, + NgtVector3, + NgtVectorPipeModule, + tapEffect, +} from '@angular-three/core'; +import { NgtSphereGeometryModule } from '@angular-three/core/geometries'; +import { + NgtAmbientLightModule, + NgtDirectionalLightModule, + NgtSpotLightModule, +} from '@angular-three/core/lights'; +import { NgtMeshStandardMaterialModule } from '@angular-three/core/materials'; +import { NgtInstancedMeshModule } from '@angular-three/core/meshes'; +import { NgtPrimitiveModule } from '@angular-three/core/primitive'; +import { NgtEffectComposerModule } from '@angular-three/postprocessing'; +import { NgtSSAOModule } from '@angular-three/postprocessing/effects'; +import { + NgtSobaEnvironmentModule, + NgtSobaSkyModule, +} from '@angular-three/soba/staging'; +import { + ChangeDetectionStrategy, + Component, + NgModule, + OnInit, + ViewChild, +} from '@angular/core'; +import * as THREE from 'three'; + +@Component({ + selector: 'storybook-object-clump', + template: ` + + + + + + + + + + + + + + + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ObjectClumpComponent {} + +@Component({ + selector: 'storybook-pointer', + template: ` + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PointerComponent extends NgtStore implements OnInit { + getSphereProps: GetByIndex = () => ({ + position: [0, 0, 0], + type: 'Kinematic', + args: [3], + }); + + @ViewChild(NgtPhysicSphere, { static: true }) + physicSphere!: NgtPhysicSphere; + + constructor(private animationFrameStore: NgtAnimationFrameStore) { + super(); + } + + ngOnInit() { + this.effect( + tapEffect(() => { + const uuid = this.animationFrameStore.register({ + callback: ({ viewport, mouse }) => { + this.physicSphere.api.position.set( + (mouse.x * viewport.width) / 2, + (mouse.y * viewport.height) / 2, + 0 + ); + }, + }); + + return () => { + this.animationFrameStore.unregister(uuid); + }; + }) + )(); + } +} + +const mat = new THREE.Matrix4(); +const vec = new THREE.Vector3(); + +@Component({ + selector: 'storybook-clump', + template: ` + + + + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ClumpComponent { + get position() { + return [ + THREE.MathUtils.randFloatSpread(20), + THREE.MathUtils.randFloatSpread(20), + THREE.MathUtils.randFloatSpread(20), + ] as NgtVector3; + } + + count = 40; + + getSphereProps: GetByIndex = () => ({ + args: [1], + mass: 1, + angularDamping: 0.1, + linearDamping: 0.65, + position: this.position as NgtTriplet, + }); + + onAnimate(object: THREE.Object3D, physicSphere: NgtPhysicSphere) { + for (let i = 0; i < this.count; i++) { + // Get current whereabouts of the instanced sphere + (object as THREE.InstancedMesh).getMatrixAt(i, mat); + // Normalize the position and multiply by a negative force. + // This is enough to drive it towards the center-point. + physicSphere.api + .at(i) + .applyForce( + vec + .setFromMatrixPosition(mat) + .normalize() + .multiplyScalar(-50) + .toArray(), + [0, 0, 0] + ); + } + } +} + +@NgModule({ + declarations: [ObjectClumpComponent, PointerComponent, ClumpComponent], + exports: [ObjectClumpComponent], + imports: [ + NgtPhysicSphereModule, + NgtInstancedMeshModule, + NgtSphereGeometryModule, + NgtCoreModule, + NgtAmbientLightModule, + NgtSpotLightModule, + NgtVectorPipeModule, + NgtDirectionalLightModule, + NgtPhysicsModule, + NgtSobaEnvironmentModule, + NgtEffectComposerModule, + NgtSSAOModule, + NgtMeshStandardMaterialModule, + NgtPrimitiveModule, + NgtCannonDebugModule, + NgtSobaSkyModule, + ], +}) +export class ObjectClumpComponentModule {} diff --git a/libs/storybook/src/cannon/object-clump/object-clump.mdx b/libs/storybook/src/cannon/object-clump/object-clump.mdx new file mode 100644 index 000000000..152e685ea --- /dev/null +++ b/libs/storybook/src/cannon/object-clump/object-clump.mdx @@ -0,0 +1,218 @@ +This is a demo forked from [R3F Object Clump](https://codesandbox.io/s/object-clump-forked-5r6bv5?file=/src/App.js) that showcases objects attracted to the center. Twitter: [https://twitter.com/0xca0a/status/1496181497677729793](https://twitter.com/0xca0a/status/1496181497677729793) + +```ts +import { + GetByIndex, + NgtPhysicsModule, + SphereProps, +} from '@angular-three/cannon'; +import { + NgtPhysicSphere, + NgtPhysicSphereModule, +} from '@angular-three/cannon/bodies'; +import { NgtCannonDebugModule } from '@angular-three/cannon/debug'; +import { + NgtAnimationFrameStore, + NgtCoreModule, + NgtStore, + NgtTriplet, + NgtVector3, + NgtVectorPipeModule, + tapEffect, +} from '@angular-three/core'; +import { NgtSphereGeometryModule } from '@angular-three/core/geometries'; +import { + NgtAmbientLightModule, + NgtDirectionalLightModule, + NgtSpotLightModule, +} from '@angular-three/core/lights'; +import { NgtMeshStandardMaterialModule } from '@angular-three/core/materials'; +import { NgtInstancedMeshModule } from '@angular-three/core/meshes'; +import { NgtPrimitiveModule } from '@angular-three/core/primitive'; +import { NgtEffectComposerModule } from '@angular-three/postprocessing'; +import { NgtSSAOModule } from '@angular-three/postprocessing/effects'; +import { + NgtSobaEnvironmentModule, + NgtSobaSkyModule, +} from '@angular-three/soba/staging'; +import { + ChangeDetectionStrategy, + Component, + NgModule, + OnInit, + ViewChild, +} from '@angular/core'; +import * as THREE from 'three'; + +@Component({ + selector: 'storybook-object-clump', + template: ` + + + + + + + + + + + + + + + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ObjectClumpComponent {} + +@Component({ + selector: 'storybook-pointer', + template: ` + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PointerComponent extends NgtStore implements OnInit { + getSphereProps: GetByIndex = () => ({ + position: [0, 0, 0], + type: 'Kinematic', + args: [3], + }); + + @ViewChild(NgtPhysicSphere, { static: true }) + physicSphere!: NgtPhysicSphere; + + constructor(private animationFrameStore: NgtAnimationFrameStore) { + super(); + } + + ngOnInit() { + this.effect( + tapEffect(() => { + const uuid = this.animationFrameStore.register({ + callback: ({ viewport, mouse }) => { + this.physicSphere.api.position.set( + (mouse.x * viewport.width) / 2, + (mouse.y * viewport.height) / 2, + 0 + ); + }, + }); + + return () => { + this.animationFrameStore.unregister(uuid); + }; + }) + )(); + } +} + +const mat = new THREE.Matrix4(); +const vec = new THREE.Vector3(); + +@Component({ + selector: 'storybook-clump', + template: ` + + + + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ClumpComponent { + get position() { + return [ + THREE.MathUtils.randFloatSpread(20), + THREE.MathUtils.randFloatSpread(20), + THREE.MathUtils.randFloatSpread(20), + ] as NgtVector3; + } + + count = 40; + + getSphereProps: GetByIndex = () => ({ + args: [1], + mass: 1, + angularDamping: 0.1, + linearDamping: 0.65, + position: this.position as NgtTriplet, + }); + + onAnimate(object: THREE.Object3D, physicSphere: NgtPhysicSphere) { + for (let i = 0; i < this.count; i++) { + // Get current whereabouts of the instanced sphere + (object as THREE.InstancedMesh).getMatrixAt(i, mat); + // Normalize the position and multiply by a negative force. + // This is enough to drive it towards the center-point. + physicSphere.api + .at(i) + .applyForce( + vec + .setFromMatrixPosition(mat) + .normalize() + .multiplyScalar(-50) + .toArray(), + [0, 0, 0] + ); + } + } +} + +@NgModule({ + declarations: [ObjectClumpComponent, PointerComponent, ClumpComponent], + exports: [ObjectClumpComponent], + imports: [ + NgtPhysicSphereModule, + NgtInstancedMeshModule, + NgtSphereGeometryModule, + NgtCoreModule, + NgtAmbientLightModule, + NgtSpotLightModule, + NgtVectorPipeModule, + NgtDirectionalLightModule, + NgtPhysicsModule, + NgtSobaEnvironmentModule, + NgtEffectComposerModule, + NgtSSAOModule, + NgtMeshStandardMaterialModule, + NgtPrimitiveModule, + NgtCannonDebugModule, + NgtSobaSkyModule, + ], +}) +export class ObjectClumpComponentModule {} +``` diff --git a/libs/storybook/src/cannon/object-clump/object-clump.stories.ts b/libs/storybook/src/cannon/object-clump/object-clump.stories.ts new file mode 100644 index 000000000..925f3ea37 --- /dev/null +++ b/libs/storybook/src/cannon/object-clump/object-clump.stories.ts @@ -0,0 +1,23 @@ +import { Meta, moduleMetadata } from '@storybook/angular'; +import { ObjectClumpComponentModule } from './object-clump.component'; +// @ts-ignore +import objectClumpDocs from './object-clump.mdx'; + +export default { + title: 'Cannon/Object Clump', + decorators: [ + moduleMetadata({ + imports: [ObjectClumpComponentModule], + }), + ], + parameters: { + docs: { page: objectClumpDocs }, + viewMode: 'story', + }, +} as Meta; + +export const Default = () => ({ + template: ` + + `, +}); diff --git a/libs/storybook/src/cannon/simple-physics/simple-physics.component.ts b/libs/storybook/src/cannon/simple-physics/simple-physics.component.ts index 62586d5fd..ecdbde0c6 100644 --- a/libs/storybook/src/cannon/simple-physics/simple-physics.component.ts +++ b/libs/storybook/src/cannon/simple-physics/simple-physics.component.ts @@ -1,4 +1,9 @@ -import { BoxProps, GetByIndex, NgtPhysicsModule } from '@angular-three/cannon'; +import { + BoxProps, + GetByIndex, + NgtPhysicsModule, + PlaneProps, +} from '@angular-three/cannon'; import { NgtPhysicBoxModule, NgtPhysicPlaneModule, @@ -54,11 +59,11 @@ import { @@ -103,9 +108,10 @@ export class SimpleSinglePhysicsComponent {} template: ` = () => ({ + args: [1000, 1000], + rotation: this.rotation as NgtTriplet, + position: this.position as NgtTriplet, + }); } @Component({ @@ -145,7 +158,7 @@ export class PlaneComponent { }) export class CubeComponent { @Input() position?: NgtVector3; - @Input() scale?: NgtVector3; + @Input() scale?: NgtVector3 = 1; rotation = [0.4, 0.2, 0.5] as NgtEuler; getCubeProps: GetByIndex = () => ({