Skip to content

Commit

Permalink
add: instancedMesh and patched AbstractMesh and basic 'object' diff
Browse files Browse the repository at this point in the history
fixes #38
fixes #61
fixes #86
  • Loading branch information
brianzinn committed Sep 9, 2020
1 parent 1dac969 commit ccdf3f5
Show file tree
Hide file tree
Showing 8 changed files with 770 additions and 218 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ With declarative (TSX/JSX) coding and HMR, you experience the same development w
![BabylonJS HMR](https://raw.githubusercontent.com/brianzinn/react-babylonjs/master/media/react-babylonjs-hmr.gif)

# @babylonjs/core API Support
1. **Node -> Mesh** - abstractMesh, mesh, node, transformNode
1. **Node -> Mesh** - abstractMesh, groundMesh, instancedLinesMesh, instancedMesh, linesMesh, mesh, node, transformNode, trailMesh

2. **Cameras** - anaglyphArcRotateCamera, anaglyphFreeCamera, anaglyphGamepadCamera, anaglyphUniversalCamera, arcFollowCamera, arcRotateCamera, camera, deviceOrientationCamera, flyCamera, followCamera, freeCamera, gamepadCamera, stereoscopicArcRotateCamera, stereoscopicFreeCamera, stereoscopicGamepadCamera, stereoscopicUniversalCamera, targetCamera, touchCamera, universalCamera, virtualJoysticksCamera, vrDeviceOrientationArcRotateCamera, vrDeviceOrientationFreeCamera, vrDeviceOrientationGamepadCamera, webVrFreeCamera, webXrCamera

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"cross-env": "^7.0.0",
"earcut": "^2.2.2",
"gsap": "^2.1.3",
"honeycomb-grid": "^3.1.7",
"lint-staged": "^8.1.0",
"lodash.camelcase": "^4.3.0",
"pixi-projection": "^0.3.11",
Expand Down
12 changes: 12 additions & 0 deletions src/PropsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,18 @@ export const checkControlDiff = (oldProp: Control | undefined, newProp: Control
})
}

export const checkObjectDiff = (oldProp: object | undefined, newProp: object | undefined, propertyName: string, changedProps: PropertyUpdate[]): void => {
propertyCheck<object>(oldProp, newProp, propertyName, PropChangeType.Primitive, changedProps, (oldProp, newProp, changedProps) => {
if (newProp !== oldProp) {
changedProps.push({
propertyName,
changeType: PropChangeType.Primitive,
value: newProp
})
}
})
}

export type PrimitiveType = string | number | undefined | null | boolean;

export const checkPrimitiveDiff = (oldProp: PrimitiveType | undefined, newProp: PrimitiveType | undefined, propertyName: string, changedProps: PropertyUpdate[]): void => {
Expand Down
637 changes: 493 additions & 144 deletions src/generatedCode.ts

Large diffs are not rendered by default.

68 changes: 60 additions & 8 deletions src/generatedProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { CustomProps } from "./CreatedInstance";
import { ModelProps } from "./model";
import { DynamicTerrain as ExtensionsDynamicTerrain } from "./extensions/DynamicTerrain";
import { AbstractScene as BabylonjsCoreAbstractScene } from "@babylonjs/core/abstractScene";
import { Node as BabylonjsCoreNode } from "@babylonjs/core/node";
import { Scene as BabylonjsCoreScene } from "@babylonjs/core/scene";
import { Camera as BabylonjsCoreCamera } from "@babylonjs/core/Cameras/camera";
import { DebugLayerTab as BabylonjsCoreDebugLayerTab } from "@babylonjs/core/Debug/debugLayer";
Expand All @@ -16,8 +15,10 @@ import { SceneLoaderAnimationGroupLoadingMode as BabylonjsCoreSceneLoaderAnimati
import { Material as BabylonjsCoreMaterial } from "@babylonjs/core/Materials/material";
import { Space as BabylonjsCoreSpace } from "@babylonjs/core/Maths/math.axis";
import { Orientation as BabylonjsCoreOrientation } from "@babylonjs/core/Maths/math.path";
import { AbstractMesh as BabylonjsCoreAbstractMesh } from "@babylonjs/core/Meshes/abstractMesh";
import { Mesh as BabylonjsCoreMesh } from "@babylonjs/core/Meshes/mesh";
import { MeshBuilder as BabylonjsCoreMeshBuilder } from "@babylonjs/core/Meshes/meshBuilder";
import { TransformNode as BabylonjsCoreTransformNode } from "@babylonjs/core/Meshes/transformNode";
import { AssetTaskState as BabylonjsCoreAssetTaskState } from "@babylonjs/core/Misc/assetsManager";
import { InspectableType as BabylonjsCoreInspectableType, IInspectable as BabylonjsCoreIInspectable } from "@babylonjs/core/Misc/iInspectable";
import { JoystickAxis as BabylonjsCoreJoystickAxis } from "@babylonjs/core/Misc/virtualJoystick";
Expand Down Expand Up @@ -55,22 +56,24 @@ import { NodeMaterialBlockConnectionPointTypes as BabylonjsCoreNodeMaterialBlock
import { NodeMaterialBlockTargets as BabylonjsCoreNodeMaterialBlockTargets } from "@babylonjs/core/Materials/Node/Enums/nodeMaterialBlockTargets";
import { NodeMaterialSystemValues as BabylonjsCoreNodeMaterialSystemValues } from "@babylonjs/core/Materials/Node/Enums/nodeMaterialSystemValues";
import { AnimatedInputBlockTypes as BabylonjsCoreAnimatedInputBlockTypes } from "@babylonjs/core/Materials/Node/Blocks/Input/animatedInputBlockTypes";
import { Node as BabylonjsCoreNode } from "@babylonjs/core/node";
import { AnimationPropertiesOverride as BabylonjsCoreAnimationPropertiesOverride } from "@babylonjs/core/Animations/animationPropertiesOverride";
import { Animation as BabylonjsCoreAnimation } from "@babylonjs/core/Animations/animation";
import { Observable as BabylonjsCoreObservable } from "@babylonjs/core/Misc/observable";
import { Behavior as BabylonjsCoreBehavior } from "@babylonjs/core/Behaviors/behavior";
import { TransformNode as BabylonjsCoreTransformNode } from "@babylonjs/core/Meshes/transformNode";
import { Vector3 as BabylonjsCoreVector3, Quaternion as BabylonjsCoreQuaternion, Matrix as BabylonjsCoreMatrix, Vector2 as BabylonjsCoreVector2, Vector4 as BabylonjsCoreVector4 } from "@babylonjs/core/Maths/math.vector";
import { DeepImmutableObject as BabylonjsCoreDeepImmutableObject, IndicesArray as BabylonjsCoreIndicesArray, FloatArray as BabylonjsCoreFloatArray } from "@babylonjs/core/types";
import { AbstractMesh as BabylonjsCoreAbstractMesh } from "@babylonjs/core/Meshes/abstractMesh";
import { AbstractActionManager as BabylonjsCoreAbstractActionManager } from "@babylonjs/core/Actions/abstractActionManager";
import { Color4 as BabylonjsCoreColor4, Color3 as BabylonjsCoreColor3 } from "@babylonjs/core/Maths/math.color";
import { Skeleton as BabylonjsCoreSkeleton } from "@babylonjs/core/Bones/skeleton";
import { SubMesh as BabylonjsCoreSubMesh } from "@babylonjs/core/Meshes/subMesh";
import { BoundingInfo as BabylonjsCoreBoundingInfo } from "@babylonjs/core/Culling/boundingInfo";
import { InstancedMesh as BabylonjsCoreInstancedMesh } from "@babylonjs/core/Meshes/instancedMesh";
import { InstancedLinesMesh as BabylonjsCoreInstancedLinesMesh, LinesMesh as BabylonjsCoreLinesMesh } from "@babylonjs/core/Meshes/linesMesh";
import { MorphTargetManager as BabylonjsCoreMorphTargetManager } from "@babylonjs/core/Morph/morphTargetManager";
import { VertexBuffer as BabylonjsCoreVertexBuffer } from "@babylonjs/core/Meshes/buffer";
import { GroundMesh as BabylonjsCoreGroundMesh } from "@babylonjs/core/Meshes/groundMesh";
import { TrailMesh as BabylonjsCoreTrailMesh } from "@babylonjs/core/Meshes/trailMesh";
import { RenderTargetTexture as BabylonjsCoreRenderTargetTexture } from "@babylonjs/core/Materials/Textures/renderTargetTexture";
import { CameraInputsManager as BabylonjsCoreCameraInputsManager } from "@babylonjs/core/Cameras/cameraInputsManager";
import { Viewport as BabylonjsCoreViewport } from "@babylonjs/core/Maths/math.viewport";
Expand Down Expand Up @@ -104,9 +107,7 @@ import { FlyCamera as BabylonjsCoreFlyCamera } from "@babylonjs/core/Cameras/fly
import { FlyCameraInputsManager as BabylonjsCoreFlyCameraInputsManager } from "@babylonjs/core/Cameras/flyCameraInputsManager";
import { FollowCamera as BabylonjsCoreFollowCamera, ArcFollowCamera as BabylonjsCoreArcFollowCamera } from "@babylonjs/core/Cameras/followCamera";
import { FollowCameraInputsManager as BabylonjsCoreFollowCameraInputsManager } from "@babylonjs/core/Cameras/followCameraInputsManager";
import { LinesMesh as BabylonjsCoreLinesMesh } from "@babylonjs/core/Meshes/linesMesh";
import { Plane as BabylonjsCorePlane } from "@babylonjs/core/Maths/math.plane";
import { GroundMesh as BabylonjsCoreGroundMesh } from "@babylonjs/core/Meshes/groundMesh";
import { SmartArray as BabylonjsCoreSmartArray, ISmartArrayLike as BabylonjsCoreISmartArrayLike } from "@babylonjs/core/Misc/smartArray";
import { Effect as BabylonjsCoreEffect } from "@babylonjs/core/Materials/effect";
import { ShaderMaterial as BabylonjsCoreShaderMaterial, IShaderMaterialOptions as BabylonjsCoreIShaderMaterialOptions } from "@babylonjs/core/Materials/shaderMaterial";
Expand Down Expand Up @@ -199,6 +200,7 @@ import { PhysicsJoint as BabylonjsCorePhysicsJoint } from "@babylonjs/core/Physi
import { PickingInfo as BabylonjsCorePickingInfo } from "@babylonjs/core/Collisions/pickingInfo";
import { WebXRDefaultExperience as BabylonjsCoreWebXRDefaultExperience } from "@babylonjs/core/XR/webXRDefaultExperience";
import { SolidParticleSystem as BabylonjsCoreSolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem";
import { IPhysicsEnginePlugin as BabylonjsCoreIPhysicsEnginePlugin } from "@babylonjs/core/Physics/IPhysicsEngine";
import { Collider as BabylonjsCoreCollider } from "@babylonjs/core/Collisions/collider";
import { Ray as BabylonjsCoreRay } from "@babylonjs/core/Culling/ray";
import { IOfflineProvider as BabylonjsCoreIOfflineProvider } from "@babylonjs/core/Offline/IOfflineProvider";
Expand All @@ -209,7 +211,6 @@ import { PointerEventTypes as BabylonjsCorePointerEventTypes, PointerInfo as Bab
import { PostProcessManager as BabylonjsCorePostProcessManager } from "@babylonjs/core/PostProcesses/postProcessManager";
import { AnimationGroup as BabylonjsCoreAnimationGroup } from "@babylonjs/core/Animations/animationGroup";
import { IParticleSystem as BabylonjsCoreIParticleSystem } from "@babylonjs/core/Particles/IParticleSystem";
import { IPhysicsEnginePlugin as BabylonjsCoreIPhysicsEnginePlugin } from "@babylonjs/core/Physics/IPhysicsEngine";

export type BabylonNode<T> = {
children?: ReactNode;
Expand All @@ -224,7 +225,12 @@ declare global {
node: FiberNodeProps & FiberNodePropsCtor & BabylonNode<BabylonjsCoreNode>;
transformNode: FiberTransformNodeProps & FiberTransformNodePropsCtor & BabylonNode<BabylonjsCoreTransformNode>;
abstractMesh: FiberAbstractMeshProps & FiberAbstractMeshPropsCtor & BabylonNode<BabylonjsCoreAbstractMesh>;
instancedMesh: FiberInstancedMeshProps & FiberInstancedMeshPropsCtor & BabylonNode<BabylonjsCoreInstancedMesh>;
instancedLinesMesh: FiberInstancedLinesMeshProps & FiberInstancedLinesMeshPropsCtor & BabylonNode<BabylonjsCoreInstancedLinesMesh>;
mesh: FiberMeshProps & FiberMeshPropsCtor & BabylonNode<BabylonjsCoreMesh>;
linesMesh: FiberLinesMeshProps & FiberLinesMeshPropsCtor & BabylonNode<BabylonjsCoreLinesMesh>;
groundMesh: FiberGroundMeshProps & FiberGroundMeshPropsCtor & BabylonNode<BabylonjsCoreGroundMesh>;
trailMesh: FiberTrailMeshProps & FiberTrailMeshPropsCtor & BabylonNode<BabylonjsCoreTrailMesh>;
camera: FiberCameraProps & FiberCameraPropsCtor & BabylonNode<BabylonjsCoreCamera>;
targetCamera: FiberTargetCameraProps & FiberTargetCameraPropsCtor & BabylonNode<BabylonjsCoreTargetCamera>;
freeCamera: FiberFreeCameraProps & FiberFreeCameraPropsCtor & BabylonNode<BabylonjsCoreFreeCamera>;
Expand Down Expand Up @@ -464,6 +470,7 @@ export type FiberAbstractMeshProps = {
'facetDepthSortFrom-y'?: number;
'facetDepthSortFrom-z'?: number;
hasVertexAlpha?: boolean;
instancedBuffers?: { [key: string]: any; };
isBlocker?: boolean;
isPickable?: boolean;
isVisible?: boolean;
Expand Down Expand Up @@ -504,6 +511,22 @@ export type FiberAbstractMeshProps = {
export type FiberAbstractMeshPropsCtor = {
name: string;
};
export type FiberInstancedMeshProps = {
renderingGroupId?: number;
setIndices?: any;
setVerticesData?: any;
} & FiberAbstractMeshProps;
export type FiberInstancedMeshPropsCtor = {
name: string;
source: BabylonjsCoreMesh;
};
export type FiberInstancedLinesMeshProps = {
intersectionThreshold?: number;
} & FiberInstancedMeshProps;
export type FiberInstancedLinesMeshPropsCtor = {
name: string;
source: BabylonjsCoreLinesMesh;
};
export type FiberMeshProps = {
addInstance?: any;
addLODLevel?: any;
Expand Down Expand Up @@ -531,6 +554,35 @@ export type FiberMeshPropsCtor = {
doNotCloneChildren?: boolean;
clonePhysicsImpostor?: boolean;
};
export type FiberLinesMeshProps = {
alpha?: number;
color?: BabylonjsCoreColor3;
color4?: any;
intersectionThreshold?: number;
material?: BabylonjsCoreMaterial;
} & FiberMeshProps;
export type FiberLinesMeshPropsCtor = {
name: string;
parent?: BabylonjsCoreNode;
source?: BabylonjsCoreLinesMesh;
doNotCloneChildren?: boolean;
useVertexColor?: boolean;
useVertexAlpha?: boolean;
};
export type FiberGroundMeshProps = {
generateOctree?: boolean;
} & FiberMeshProps;
export type FiberGroundMeshPropsCtor = {
name: string;
};
export type FiberTrailMeshProps = {} & FiberMeshProps;
export type FiberTrailMeshPropsCtor = {
name: string;
generator: BabylonjsCoreTransformNode;
diameter?: number;
length?: number;
autoStart?: boolean;
};
export type FiberCameraProps = {
cameraRigMode?: number;
customRenderTargets?: BabylonjsCoreRenderTargetTexture[];
Expand Down Expand Up @@ -2979,7 +3031,7 @@ export type FiberSceneProps = {
onAfterCameraRenderObservable?: any;
onAfterDrawPhaseObservable?: any;
onAfterParticlesRenderingObservable?: any;
onAfterPhysicsObservable?: BabylonjsCoreObservable<BabylonjsCoreScene>;
onAfterPhysicsObservable?: any;
onAfterRenderCameraObservable?: any;
onAfterRenderingGroupObservable?: any;
onAfterRenderObservable?: any;
Expand All @@ -2991,7 +3043,7 @@ export type FiberSceneProps = {
onBeforeCameraRenderObservable?: any;
onBeforeDrawPhaseObservable?: any;
onBeforeParticlesRenderingObservable?: any;
onBeforePhysicsObservable?: BabylonjsCoreObservable<BabylonjsCoreScene>;
onBeforePhysicsObservable?: any;
onBeforeRenderingGroupObservable?: any;
onBeforeRenderObservable?: any;
onBeforeRenderTargetsRenderObservable?: any;
Expand Down
90 changes: 90 additions & 0 deletions stories/babylonjs/Basic/instances.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, { useState, useCallback } from 'react'
import { Engine, Scene } from '../../../dist/react-babylonjs'
import { Vector3, Color3, Color4 } from '@babylonjs/core'
import { defineGrid, extendHex } from 'honeycomb-grid'
import '../../style.css'

export default { title: 'Babylon Basic' };

const GRID_WIDTH = 60;
const GRID_HEIGHT = 40;
const HOVER_COLOR = new Color4(0.8, 0.8, 0.8, 1);

export const Instances = () => {
const [_, setState] = useState(false);
const createUpdate = () => {
setState((state) => !state);
};

// const hexRef = useRef<CreatedInstance<Mesh>>(null);
const [hexMesh, setHexMesh] = useState(null);
const hexRef = useCallback((node) => {
if (node) {
const mesh = node.hostInstance;
mesh.registerInstancedBuffer("color", 4);
setHexMesh(mesh);
}
}, []);

const Hex = extendHex({
size: 1, // default: 1
orientation: 'flat', // default: 'pointy'
color: new Color4(0, 0.68, 1),
hovered: false
})

// create a Grid factory that uses the Hex factory:
const Grid = defineGrid(Hex)

// create a rectangle grid with each tile assigned a random color:
const grid = Grid.rectangle({ width: GRID_WIDTH, height: GRID_HEIGHT, onCreate: (hex) => {
hex.color = new Color4(Math.random(), Math.random(), Math.random(), 1);
hex.isHovered = Math.random() < 0.1;
} })

return (
<div className="App">
<button onClick={createUpdate}>Change hex colours</button>
<Engine antialias adaptToDeviceRatio canvasId="babylonJS">
<Scene clearColor={Color4.FromColor3(Color3.White())}>
<arcRotateCamera
name="arc"
target={Vector3.Zero()}
minZ={0.001}
alpha={-Math.PI / 2}
beta={Math.PI / 1.2}
radius={Math.max(GRID_WIDTH, GRID_HEIGHT) * 1.5}
/>
<hemisphericLight
name="light1"
intensity={0.9}
direction={Vector3.Down()}
/>
<disc
ref={hexRef}
name="hex"
radius={1}
tessellation={6}
isVisible={false}
/>
{hexMesh &&
Array.from(grid.entries()).map(entry => {
const [i, tile] = entry;
const {x, y} = tile.toPoint();
console.log(`${i}->{${x},${y}} (${tile.width()})`)
return (
<instancedMesh
source={hexMesh}
key={i}
name={`hex-${i}`}
position={new Vector3((x+tile.width()/2) - (GRID_WIDTH * 0.75), (y+tile.height()/2) - (Math.sqrt(3) * GRID_HEIGHT / 2), 0)}
instancedBuffers={{color: tile.isHovered ? HOVER_COLOR : tile.color}}
/>
)
})
}
</Scene>
</Engine>
</div>
);
}
56 changes: 45 additions & 11 deletions stories/babylonjs/Integrations/react-three-gui.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import { Engine, Scene, useCustomPropsHandler, CustomPropsHandler, PropChangeType } from 'react-babylonjs';
import { animated as a } from 'react-babylon-spring';
import { Vector3, Color3, Texture, Mesh } from '@babylonjs/core';
import { Controls, useControl } from 'react-three-gui';
import { Controls, useControl, ControlsContext } from 'react-three-gui';

import '../../style.css'

Expand Down Expand Up @@ -125,18 +125,52 @@ const Box = () => {
}

export const ReactThreeGui = () => {
const [controls, setControls] = React.useState([]);
// Persist values between reloads
const values = React.useRef(new Map());
// GUI control state setters
const gui = React.useRef(new Map());
// useControl state setters
const state = React.useRef(new Map());

const context = {
values,
gui,
state,
controls,
addControl: (control) => {
control.id = String(Math.random());
setControls(ctrls => {
// control.id = control.id ?? String(ctrls.length);
return [...ctrls, control];
});
return control;
},
removeControl: (ctrl) => {
setControls(ctrls => ctrls.filter(c => c.id !== ctrl.id));
},
};

return (
<div>
<Engine antialias adaptToDeviceRatio canvasId='babylonCanvas'>
<Scene>
<pointLight position={new Vector3(0, 2, 2)} intensity={0.2} />
<hemisphericLight name='light1' intensity={0.7} direction={Vector3.Up()} />
<arcRotateCamera name="arc" target={new Vector3(0, 1, 0)} minZ={0.001}
alpha={-Math.PI / 2} beta={(0.5 + (Math.PI / 4))} radius={5} />
<Box />
</Scene>
</Engine>
<Controls />
<ControlsContext.Provider value={context}>
<ControlsContext.Consumer>
{value => (
<Engine antialias adaptToDeviceRatio canvasId='babylonCanvas'>
<Scene>
<pointLight position={new Vector3(0, 2, 2)} intensity={0.2} />
<hemisphericLight name='light1' intensity={0.7} direction={Vector3.Up()} />
<arcRotateCamera name="arc" target={new Vector3(0, 1, 0)} minZ={0.001}
alpha={-Math.PI / 2} beta={(0.5 + (Math.PI / 4))} radius={5} />
<ControlsContext.Provider value={value}>
<Box />
</ControlsContext.Provider>
</Scene>
</Engine>
)}
</ControlsContext.Consumer>
<Controls />
</ControlsContext.Provider>
</div>
);
};
Expand Down
Loading

0 comments on commit ccdf3f5

Please sign in to comment.