r3f-ify jsCadController

This commit is contained in:
Kurt Hutten
2021-08-21 11:04:01 +10:00
parent ac233a5920
commit b0647171d8
4 changed files with 65 additions and 45 deletions

View File

@@ -31,11 +31,6 @@ function Asset({ geometry: incomingGeo }) {
const colorMap = useTexture(texture) const colorMap = useTexture(texture)
if (!incomingGeo) return null if (!incomingGeo) return null
if (incomingGeo.length)
return incomingGeo.map((shape, index) => (
<primitive object={shape} key={index} />
))
return ( return (
<group dispose={null}> <group dispose={null}>
<mesh ref={mesh} scale={[1, 1, 1]} geometry={incomingGeo}> <mesh ref={mesh} scale={[1, 1, 1]} geometry={incomingGeo}>
@@ -166,6 +161,10 @@ const IdeViewer = ({ Loading }) => {
setImage(state.objectData?.type === 'png' && state.objectData?.data) setImage(state.objectData?.type === 'png' && state.objectData?.data)
setIsDragging(false) setIsDragging(false)
}, [state.objectData?.type, state.objectData?.data]) }, [state.objectData?.type, state.objectData?.data])
const R3FComponent = React.useMemo(
() => state.objectData?.type === 'r3f-component' && state.objectData?.data,
[state.objectData?.type, state.objectData?.data]
)
// the following are tailwind colors in hex, can't use these classes to color three.js meshes. // the following are tailwind colors in hex, can't use these classes to color three.js meshes.
const pink400 = '#F472B6' const pink400 = '#F472B6'
@@ -268,6 +267,7 @@ const IdeViewer = ({ Loading }) => {
{state.objectData?.type === 'geometry' && state.objectData?.data && ( {state.objectData?.type === 'geometry' && state.objectData?.data && (
<Asset geometry={state.objectData?.data} /> <Asset geometry={state.objectData?.data} />
)} )}
{R3FComponent && <R3FComponent />}
</Canvas> </Canvas>
</div> </div>
<DelayedPingAnimation isLoading={state.isLoading} /> <DelayedPingAnimation isLoading={state.isLoading} />

View File

@@ -21,6 +21,8 @@ export interface RenderArgs {
} }
} }
export type ArtifactTypes = 'stl' | 'png' | 'geometry' | 'r3f-component'
export interface HealthyResponse { export interface HealthyResponse {
status: 'healthy' status: 'healthy'
message: { message: {
@@ -30,7 +32,7 @@ export interface HealthyResponse {
} }
objectData: { objectData: {
data: any data: any
type: 'stl' | 'png' | 'geometry' type: ArtifactTypes
} }
customizerParams?: any[] customizerParams?: any[]
currentParameters?: RawCustomizerParams currentParameters?: RawCustomizerParams

View File

@@ -31,23 +31,37 @@ const materials = {
} }
materials.lines = materials.line materials.lines = materials.line
function CSG2Object3D(obj) { interface CsgObj {
const { vertices, indices, color, transforms } = obj vertices: Float32Array
indices: Uint16Array
color?: [number, number, number, number]
transforms: number[]
type: 'mesh' | 'line' | 'lines'
}
const materialDef = materials[obj.type] function CSGArray2R3fComponent(Csgs: CsgObj[]): React.ReactNode {
return () =>
Csgs.map(({ vertices, indices, color, transforms, type }, index) => {
const materialDef = materials[type]
if (!materialDef) { if (!materialDef) {
console.error('Can not hangle object type: ' + obj.type, obj) console.error('Can not hangle object type: ' + type, {
vertices,
indices,
color,
transforms,
type,
})
return null return null
} }
let material = materialDef.def let material = materialDef.def
if (color) { if (color) {
const c = color const [r, g, b, opacity] = color
material = materialDef.material({ material = materialDef.material({
color: new Color(c[0], c[1], c[2]), color: new Color(r, g, b),
flatShading: true, flatShading: true,
opacity: c[3] === void 0 ? 1 : c[3], opacity: opacity === void 0 ? 1 : opacity,
transparent: c[3] != 1 && c[3] !== void 0, transparent: opacity != 1 && opacity !== void 0,
}) })
} }
@@ -55,7 +69,7 @@ function CSG2Object3D(obj) {
geo.setAttribute('position', new BufferAttribute(vertices, 3)) geo.setAttribute('position', new BufferAttribute(vertices, 3))
let mesh let mesh
switch (obj.type) { switch (type) {
case 'mesh': case 'mesh':
geo.setIndex(new BufferAttribute(indices, 1)) geo.setIndex(new BufferAttribute(indices, 1))
mesh = new Mesh(geo, material) mesh = new Mesh(geo, material)
@@ -68,7 +82,8 @@ function CSG2Object3D(obj) {
break break
} }
if (transforms) mesh.applyMatrix4({ elements: transforms }) if (transforms) mesh.applyMatrix4({ elements: transforms })
return mesh return <primitive object={mesh} key={index} />
})
} }
let scriptWorker let scriptWorker
@@ -143,8 +158,8 @@ export const render: DefaultKernelExport['render'] = async ({
} else { } else {
workerHelper.resolver( workerHelper.resolver(
createHealthyResponse({ createHealthyResponse({
type: 'geometry', type: 'r3f-component',
data: data.entities.map(CSG2Object3D).filter((o) => o), data: CSGArray2R3fComponent(data.entities),
consoleMessage: data.scriptStats, consoleMessage: data.scriptStats,
date: new Date(), date: new Date(),
customizerParams: jsCadToCadhubParams(parameterDefinitions || []), customizerParams: jsCadToCadhubParams(parameterDefinitions || []),

View File

@@ -1,7 +1,10 @@
import { useReducer } from 'react' import { useReducer } from 'react'
import { cadPackages } from 'src/helpers/cadPackages' import { cadPackages } from 'src/helpers/cadPackages'
import type { RootState } from '@react-three/fiber' import type { RootState } from '@react-three/fiber'
import type { RawCustomizerParams } from 'src/helpers/cadPackages/common' import type {
RawCustomizerParams,
ArtifactTypes,
} from 'src/helpers/cadPackages/common'
import { CadhubParams } from 'src/components/Customizer/customizerConverter' import { CadhubParams } from 'src/components/Customizer/customizerConverter'
function withThunk(dispatch, getState) { function withThunk(dispatch, getState) {
@@ -113,7 +116,7 @@ export interface State {
consoleMessages: { type: 'message' | 'error'; message: string; time: Date }[] consoleMessages: { type: 'message' | 'error'; message: string; time: Date }[]
code: string code: string
objectData: { objectData: {
type: 'INIT' | 'stl' | 'png' | 'geometry' type: 'INIT' | ArtifactTypes
data: any data: any
quality: 'low' | 'high' quality: 'low' | 'high'
} }