-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vector3 param type #477
base: alpha
Are you sure you want to change the base?
vector3 param type #477
Changes from all commits
2f279c4
aa40e71
b22d33e
d497aec
430dde1
a551600
86621de
e322ad1
b7e7666
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* TODO: This CSS will eventually be removed when Vector3 is a dumb (compound) component in core */ | ||
.container { | ||
display: flex; | ||
flex-direction: row; | ||
align-items: center; | ||
gap: 0.5rem; | ||
height: 100%; | ||
} | ||
|
||
.item { | ||
flex: 1; | ||
height: 100%; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { useRef } from 'react' | ||
import { useInterval } from 'usehooks-ts' | ||
import { NodeParamVector3 } from '@hedron/engine' | ||
import c from './ParamVector3.module.css' | ||
import { FloatSlider, FloatSliderHandle } from '@components/core/FloatSlider/FloatSlider' | ||
import { useOnNodeValueChange } from '@components/hooks/useOnNodeValueChange' | ||
import { engineStore, useEngineStore } from '@renderer/engine' | ||
|
||
interface ParamVector3Props { | ||
id: string | ||
} | ||
|
||
const SingleSlider = ({ id }: ParamVector3Props) => { | ||
const ref = useRef<FloatSliderHandle>(null) | ||
const onValueChange = useOnNodeValueChange(id) | ||
|
||
useInterval(() => { | ||
const nodeValue = engineStore.getState().nodeValues[id] | ||
if (typeof nodeValue !== 'number') { | ||
throw new Error('SingleSlider value was not a number') | ||
} | ||
ref.current?.drawBar(nodeValue) | ||
}, 100) | ||
|
||
return <FloatSlider ref={ref} onValueChange={onValueChange} /> | ||
} | ||
|
||
export const ParamVector3 = ({ id }: ParamVector3Props) => { | ||
const node = useEngineStore((state) => state.nodes[id] as NodeParamVector3) | ||
|
||
const { childNodeIds } = node | ||
|
||
return ( | ||
<div className={c.container}> | ||
{childNodeIds.map((childId) => ( | ||
<div key={childId} className={c.item}> | ||
<SingleSlider key={childId} id={childId} /> | ||
</div> | ||
))} | ||
</div> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
export * from './HedronEngine' | ||
export * from './HedronEngine/HedronEngine' | ||
export type * from '@store/types' | ||
export * from '@store/types' | ||
import './globalVars' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { EngineState } from '@store/types' | ||
|
||
// Get the values of the parameters of a sketch, dealing with child nodes | ||
export const getSketchParamValues = (state: EngineState, sketchId: string) => { | ||
const { sketches, nodeValues, nodes } = state | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const paramValues: { [key: string]: any } = {} | ||
const sketch = sketches[sketchId] | ||
|
||
sketch.paramIds.forEach((id) => { | ||
const { key, valueType } = nodes[id] | ||
|
||
let value | ||
|
||
if (valueType === 'vector3') { | ||
// Return an array of values for vector3 | ||
const childNodeIds = nodes[id].childNodeIds | ||
value = childNodeIds.map((childNodeId) => nodeValues[childNodeId]) | ||
} else { | ||
value = nodeValues[id] | ||
} | ||
|
||
paramValues[key] = value | ||
}) | ||
|
||
return paramValues | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { EngineState, NodeTypes, SketchConfigParam } from '@store/types' | ||
import { createUniqueId } from '@utils/createUniqueId' | ||
|
||
const vector3Keys = ['x', 'y', 'z'] | ||
|
||
export const addNode = ( | ||
state: EngineState, | ||
paramId: string, | ||
sketchId: string, | ||
{ key, valueType = NodeTypes.Number, defaultValue }: SketchConfigParam, | ||
) => { | ||
if (valueType === NodeTypes.Vector3) { | ||
if (!Array.isArray(defaultValue)) { | ||
throw new Error(`Expected defaultValue to be an array for Vector3 type`) | ||
} | ||
|
||
const childNodeIds = Array.from({ length: 3 }, createUniqueId) as [string, string, string] | ||
|
||
state.nodes[paramId] = { | ||
id: paramId, | ||
key, | ||
type: 'param', | ||
valueType, | ||
sketchId, | ||
childNodeIds, | ||
} | ||
|
||
childNodeIds.forEach((childNodeId, index) => { | ||
state.nodes[childNodeId] = { | ||
id: childNodeId, | ||
key: vector3Keys[index], | ||
type: 'param', | ||
valueType: NodeTypes.Number, | ||
sketchId, | ||
} | ||
}) | ||
|
||
defaultValue.forEach((value: number, index: number) => { | ||
state.nodeValues[childNodeIds[index]] = value | ||
}) | ||
} else { | ||
state.nodes[paramId] = { | ||
id: paramId, | ||
key, | ||
type: 'param' as const, | ||
valueType, | ||
sketchId, | ||
} | ||
|
||
// Set the default value if it matches the valueType. | ||
if ( | ||
(typeof defaultValue === 'number' && valueType === NodeTypes.Number) || | ||
(typeof defaultValue === 'boolean' && valueType === NodeTypes.Boolean) || | ||
(typeof defaultValue === 'string' && valueType === NodeTypes.Enum) | ||
) { | ||
state.nodeValues[paramId] = defaultValue | ||
} else { | ||
throw new Error( | ||
`valueType of param ${key} does not match defaultValue for sketch ${sketchId}`, | ||
) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,9 +2,10 @@ const { THREE } = window.HEDRON.dependencies | |
const geomSize = 1 | ||
|
||
export default class Solid { | ||
root = new THREE.Group() | ||
|
||
constructor() { | ||
// All sketches need root property to add things to | ||
this.root = new THREE.Group() | ||
|
||
this.meshes = {} | ||
|
||
|
@@ -39,6 +40,8 @@ export default class Solid { | |
this.root.rotation.y += params.rotSpeedY * baseSpeed * deltaFrame | ||
this.root.rotation.z += params.rotSpeedZ * baseSpeed * deltaFrame | ||
|
||
this.root.position.set(...params.position) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here the array format works perfectly for three js, having it as object with |
||
|
||
// Update scale using params | ||
this.root.scale.set(params.scale, params.scale, params.scale) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're getting all child nodes and creating an array to be handed to the sketch. Is that how users will want it? We could also hand it back as an object with
x
,y
andz
properties (orr
,g
,b
for colors...). Part of me thinks an array is simplest and the user can deal with it how they please.