fix sketch plan orientation
This commit is contained in:
@ -41,6 +41,7 @@ function App() {
|
|||||||
ast,
|
ast,
|
||||||
setError,
|
setError,
|
||||||
errorState,
|
errorState,
|
||||||
|
setProgramMemory,
|
||||||
} = useStore((s) => ({
|
} = useStore((s) => ({
|
||||||
editorView: s.editorView,
|
editorView: s.editorView,
|
||||||
setEditorView: s.setEditorView,
|
setEditorView: s.setEditorView,
|
||||||
@ -58,6 +59,7 @@ function App() {
|
|||||||
formatCode: s.formatCode,
|
formatCode: s.formatCode,
|
||||||
setError: s.setError,
|
setError: s.setError,
|
||||||
errorState: s.errorState,
|
errorState: s.errorState,
|
||||||
|
setProgramMemory: s.setProgramMemory,
|
||||||
}))
|
}))
|
||||||
// const onChange = React.useCallback((value: string, viewUpdate: ViewUpdate) => {
|
// const onChange = React.useCallback((value: string, viewUpdate: ViewUpdate) => {
|
||||||
const onChange = (value: string, viewUpdate: ViewUpdate) => {
|
const onChange = (value: string, viewUpdate: ViewUpdate) => {
|
||||||
@ -103,6 +105,7 @@ function App() {
|
|||||||
},
|
},
|
||||||
_sketch: [],
|
_sketch: [],
|
||||||
})
|
})
|
||||||
|
setProgramMemory(programMemory)
|
||||||
const geos: ViewerArtifact[] =
|
const geos: ViewerArtifact[] =
|
||||||
programMemory?.return?.flatMap(
|
programMemory?.return?.flatMap(
|
||||||
({ name }: { name: string }) =>
|
({ name }: { name: string }) =>
|
||||||
|
@ -28,6 +28,7 @@ export const Toolbar = () => {
|
|||||||
sketchMode: 'sketchEdit',
|
sketchMode: 'sketchEdit',
|
||||||
pathToNode: guiMode.pathToNode,
|
pathToNode: guiMode.pathToNode,
|
||||||
quaternion: guiMode.quaternion,
|
quaternion: guiMode.quaternion,
|
||||||
|
position: guiMode.position,
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
className="border m-1 px-1 rounded"
|
className="border m-1 px-1 rounded"
|
||||||
|
@ -65,6 +65,7 @@ export const BasePlanes = () => {
|
|||||||
mode: 'sketch',
|
mode: 'sketch',
|
||||||
sketchMode: 'sketchEdit',
|
sketchMode: 'sketchEdit',
|
||||||
quaternion,
|
quaternion,
|
||||||
|
position: [0, 0, 0],
|
||||||
pathToNode,
|
pathToNode,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import {
|
|||||||
getNodeFromPath,
|
getNodeFromPath,
|
||||||
CallExpression,
|
CallExpression,
|
||||||
changeArguments,
|
changeArguments,
|
||||||
|
VariableDeclarator,
|
||||||
} from '../lang/abstractSyntaxTree'
|
} from '../lang/abstractSyntaxTree'
|
||||||
import { ViewerArtifact } from '../lang/executor'
|
import { ViewerArtifact } from '../lang/executor'
|
||||||
import { BufferGeometry } from 'three'
|
import { BufferGeometry } from 'three'
|
||||||
@ -11,6 +12,7 @@ import { useStore } from '../useStore'
|
|||||||
import { isOverlapping } from '../lib/utils'
|
import { isOverlapping } from '../lib/utils'
|
||||||
import { LineGeos } from '../lang/engine'
|
import { LineGeos } from '../lang/engine'
|
||||||
import { Vector3, DoubleSide, Quaternion, Vector2 } from 'three'
|
import { Vector3, DoubleSide, Quaternion, Vector2 } from 'three'
|
||||||
|
import { combineTransformsAlt } from '../lang/sketch'
|
||||||
|
|
||||||
function SketchLine({
|
function SketchLine({
|
||||||
geo,
|
geo,
|
||||||
@ -129,9 +131,7 @@ function MovingSphere({
|
|||||||
|
|
||||||
const { setHighlightRange, guiMode, ast, updateAst } = useStore((s) => ({
|
const { setHighlightRange, guiMode, ast, updateAst } = useStore((s) => ({
|
||||||
setHighlightRange: s.setHighlightRange,
|
setHighlightRange: s.setHighlightRange,
|
||||||
selectionRange: s.selectionRange,
|
|
||||||
guiMode: s.guiMode,
|
guiMode: s.guiMode,
|
||||||
setGuiMode: s.setGuiMode,
|
|
||||||
ast: s.ast,
|
ast: s.ast,
|
||||||
updateAst: s.updateAst,
|
updateAst: s.updateAst,
|
||||||
}))
|
}))
|
||||||
@ -173,11 +173,13 @@ function MovingSphere({
|
|||||||
}, [isMouseDown, ast])
|
}, [isMouseDown, ast])
|
||||||
|
|
||||||
let clickDetectPlaneQuaternion = new Quaternion()
|
let clickDetectPlaneQuaternion = new Quaternion()
|
||||||
|
let position = new Vector3(0, 0, 0)
|
||||||
if (
|
if (
|
||||||
guiMode.mode === 'canEditSketch' ||
|
guiMode.mode === 'canEditSketch' ||
|
||||||
(guiMode.mode === 'sketch' && guiMode.sketchMode === 'sketchEdit')
|
(guiMode.mode === 'sketch' && guiMode.sketchMode === 'sketchEdit')
|
||||||
) {
|
) {
|
||||||
clickDetectPlaneQuaternion = guiMode.quaternion.clone()
|
clickDetectPlaneQuaternion = guiMode.quaternion.clone()
|
||||||
|
position = new Vector3(...guiMode.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -201,7 +203,7 @@ function MovingSphere({
|
|||||||
</mesh>
|
</mesh>
|
||||||
{isMouseDown && (
|
{isMouseDown && (
|
||||||
<mesh
|
<mesh
|
||||||
position={[0, 0, -0.05]}
|
position={position}
|
||||||
quaternion={clickDetectPlaneQuaternion}
|
quaternion={clickDetectPlaneQuaternion}
|
||||||
onPointerMove={(a) => {
|
onPointerMove={(a) => {
|
||||||
const point = a.point
|
const point = a.point
|
||||||
@ -264,12 +266,13 @@ export function RenderViewerArtifacts({
|
|||||||
artifact: ViewerArtifact
|
artifact: ViewerArtifact
|
||||||
forceHighlight?: boolean
|
forceHighlight?: boolean
|
||||||
}) {
|
}) {
|
||||||
const { selectionRange, guiMode, ast, setGuiMode } = useStore(
|
const { selectionRange, guiMode, ast, setGuiMode, programMemory } = useStore(
|
||||||
({ selectionRange, guiMode, ast, setGuiMode }) => ({
|
({ selectionRange, guiMode, ast, setGuiMode, programMemory }) => ({
|
||||||
selectionRange,
|
selectionRange,
|
||||||
guiMode,
|
guiMode,
|
||||||
ast,
|
ast,
|
||||||
setGuiMode,
|
setGuiMode,
|
||||||
|
programMemory,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
const [editorCursor, setEditorCursor] = useState(false)
|
const [editorCursor, setEditorCursor] = useState(false)
|
||||||
@ -287,20 +290,16 @@ export function RenderViewerArtifacts({
|
|||||||
ast
|
ast
|
||||||
) {
|
) {
|
||||||
const pathToNode = getNodePathFromSourceRange(ast, artifact.sourceRange)
|
const pathToNode = getNodePathFromSourceRange(ast, artifact.sourceRange)
|
||||||
const piper = getNodeFromPath(ast, pathToNode, 'PipeExpression')
|
const varDec: VariableDeclarator = getNodeFromPath(
|
||||||
const quaternion = new Quaternion()
|
ast,
|
||||||
if (piper.type === 'PipeExpression') {
|
pathToNode,
|
||||||
const rotateName = piper?.body?.[1]?.callee?.name
|
'VariableDeclarator'
|
||||||
const rotateValue = piper?.body?.[1]?.arguments[0].value
|
)
|
||||||
let rotateAxis = new Vector3(1, 0, 0)
|
const varName = varDec?.id?.name
|
||||||
if (rotateName === 'ry') {
|
const { quaternion, position } = combineTransformsAlt(
|
||||||
rotateAxis = new Vector3(0, 1, 0)
|
programMemory.root[varName]
|
||||||
} else if (rotateName === 'rz') {
|
)
|
||||||
rotateAxis = new Vector3(0, 0, 1)
|
setGuiMode({ mode: 'canEditSketch', pathToNode, quaternion, position })
|
||||||
}
|
|
||||||
quaternion.setFromAxisAngle(rotateAxis, (Math.PI * rotateValue) / 180)
|
|
||||||
}
|
|
||||||
setGuiMode({ mode: 'canEditSketch', pathToNode, quaternion })
|
|
||||||
} else if (
|
} else if (
|
||||||
!shouldHighlight &&
|
!shouldHighlight &&
|
||||||
guiMode.mode === 'canEditSketch' &&
|
guiMode.mode === 'canEditSketch' &&
|
||||||
|
@ -26,6 +26,7 @@ export const SketchPlane = () => {
|
|||||||
new Vector3(1, 0, 0),
|
new Vector3(1, 0, 0),
|
||||||
Math.PI / 2
|
Math.PI / 2
|
||||||
)
|
)
|
||||||
|
let position = guiMode.position
|
||||||
const gridQuaternion = new Quaternion().multiplyQuaternions(
|
const gridQuaternion = new Quaternion().multiplyQuaternions(
|
||||||
guiMode.quaternion,
|
guiMode.quaternion,
|
||||||
temp
|
temp
|
||||||
@ -35,6 +36,7 @@ export const SketchPlane = () => {
|
|||||||
<>
|
<>
|
||||||
<mesh
|
<mesh
|
||||||
quaternion={clickDetectQuaternion}
|
quaternion={clickDetectQuaternion}
|
||||||
|
position={position}
|
||||||
name={sketchGridName}
|
name={sketchGridName}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
if (guiMode.sketchMode !== 'points') {
|
if (guiMode.sketchMode !== 'points') {
|
||||||
@ -77,6 +79,7 @@ export const SketchPlane = () => {
|
|||||||
<gridHelper
|
<gridHelper
|
||||||
args={[30, 40, 'blue', 'hotpink']}
|
args={[30, 40, 'blue', 'hotpink']}
|
||||||
quaternion={gridQuaternion}
|
quaternion={gridQuaternion}
|
||||||
|
position={position}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@ -377,7 +377,7 @@ function makeValue(
|
|||||||
throw new Error('Expected a previous Value if statement to match')
|
throw new Error('Expected a previous Value if statement to match')
|
||||||
}
|
}
|
||||||
|
|
||||||
interface VariableDeclarator extends GeneralStatement {
|
export interface VariableDeclarator extends GeneralStatement {
|
||||||
type: 'VariableDeclarator'
|
type: 'VariableDeclarator'
|
||||||
id: Identifier
|
id: Identifier
|
||||||
init: Value
|
init: Value
|
||||||
|
@ -193,8 +193,6 @@ export const sketchFns = {
|
|||||||
if (!_programMemory._sketch) {
|
if (!_programMemory._sketch) {
|
||||||
throw new Error('No sketch to draw on')
|
throw new Error('No sketch to draw on')
|
||||||
}
|
}
|
||||||
const lastPath: Path =
|
|
||||||
_programMemory._sketch[_programMemory._sketch.length - 1]
|
|
||||||
let from = getCoordsFromPaths(
|
let from = getCoordsFromPaths(
|
||||||
programMemory?._sketch,
|
programMemory?._sketch,
|
||||||
programMemory?._sketch.length - 1
|
programMemory?._sketch.length - 1
|
||||||
@ -238,33 +236,8 @@ export const sketchFns = {
|
|||||||
: (sketchVal as SketchGeo) // TODO fix types
|
: (sketchVal as SketchGeo) // TODO fix types
|
||||||
}
|
}
|
||||||
|
|
||||||
type PreviousTransforms = {
|
|
||||||
rotation: Quaternion
|
|
||||||
transform: [number, number, number]
|
|
||||||
}[]
|
|
||||||
const collectTransforms = (
|
|
||||||
sketchVal: SketchGeo | ExtrudeGeo | Transform,
|
|
||||||
previousTransforms: PreviousTransforms = []
|
|
||||||
): PreviousTransforms => {
|
|
||||||
if (sketchVal.type !== 'transform') return previousTransforms
|
|
||||||
const newTransforms = [
|
|
||||||
...previousTransforms,
|
|
||||||
{
|
|
||||||
rotation: sketchVal.rotation,
|
|
||||||
transform: sketchVal.transform,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
return collectTransforms(sketchVal.sketch, newTransforms)
|
|
||||||
}
|
|
||||||
const sketch = getSketchGeo(sketchVal)
|
const sketch = getSketchGeo(sketchVal)
|
||||||
const previousTransforms = collectTransforms(sketchVal)
|
const { position, quaternion } = combineTransforms(sketchVal)
|
||||||
const position = new Vector3(0, 0, 0)
|
|
||||||
const quaternion = new Quaternion()
|
|
||||||
previousTransforms.forEach(({ rotation, transform }) => {
|
|
||||||
quaternion.multiply(rotation)
|
|
||||||
position.applyQuaternion(rotation.clone().invert())
|
|
||||||
position.add(new Vector3(...transform))
|
|
||||||
})
|
|
||||||
|
|
||||||
const extrudeFaces: ExtrudeFace[] = []
|
const extrudeFaces: ExtrudeFace[] = []
|
||||||
sketch.sketch.map((line, index) => {
|
sketch.sketch.map((line, index) => {
|
||||||
@ -284,7 +257,7 @@ export const sketchFns = {
|
|||||||
extrudeFaces.push({
|
extrudeFaces.push({
|
||||||
type: 'extrudeFace',
|
type: 'extrudeFace',
|
||||||
quaternion,
|
quaternion,
|
||||||
translate: [position.x, position.y, position.z],
|
translate: position,
|
||||||
geo,
|
geo,
|
||||||
sourceRanges: [line.sourceRange, sourceRange],
|
sourceRanges: [line.sourceRange, sourceRange],
|
||||||
})
|
})
|
||||||
@ -333,3 +306,65 @@ function translate(
|
|||||||
sourceRange,
|
sourceRange,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PreviousTransforms = {
|
||||||
|
rotation: Quaternion
|
||||||
|
transform: [number, number, number]
|
||||||
|
}[]
|
||||||
|
|
||||||
|
function collectTransforms(
|
||||||
|
sketchVal: SketchGeo | ExtrudeGeo | Transform,
|
||||||
|
previousTransforms: PreviousTransforms = []
|
||||||
|
): PreviousTransforms {
|
||||||
|
if (sketchVal.type !== 'transform') return previousTransforms
|
||||||
|
const newTransforms = [
|
||||||
|
...previousTransforms,
|
||||||
|
{
|
||||||
|
rotation: sketchVal.rotation,
|
||||||
|
transform: sketchVal.transform,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
return collectTransforms(sketchVal.sketch, newTransforms)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function combineTransforms(
|
||||||
|
sketchVal: SketchGeo | ExtrudeGeo | Transform
|
||||||
|
): {
|
||||||
|
quaternion: Quaternion
|
||||||
|
position: [number, number, number]
|
||||||
|
} {
|
||||||
|
const previousTransforms = collectTransforms(sketchVal)
|
||||||
|
const position = new Vector3(0, 0, 0)
|
||||||
|
const quaternion = new Quaternion()
|
||||||
|
previousTransforms.forEach(({ rotation, transform }) => {
|
||||||
|
quaternion.multiply(rotation)
|
||||||
|
position.applyQuaternion(rotation.clone().invert())
|
||||||
|
position.add(new Vector3(...transform))
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
quaternion,
|
||||||
|
position: [position.x, position.y, position.z],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function combineTransformsAlt(
|
||||||
|
sketchVal: SketchGeo | ExtrudeGeo | Transform
|
||||||
|
): {
|
||||||
|
quaternion: Quaternion
|
||||||
|
position: [number, number, number]
|
||||||
|
} {
|
||||||
|
const previousTransforms = collectTransforms(sketchVal)
|
||||||
|
let rotationQuaternion = new Quaternion()
|
||||||
|
let position = new Vector3(0, 0, 0)
|
||||||
|
previousTransforms.reverse().forEach(({ rotation, transform }) => {
|
||||||
|
const newQuant = rotation.clone()
|
||||||
|
newQuant.multiply(rotationQuaternion)
|
||||||
|
rotationQuaternion.copy(newQuant)
|
||||||
|
position.applyQuaternion(rotation)
|
||||||
|
position.add(new Vector3(...transform))
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
quaternion: rotationQuaternion,
|
||||||
|
position: [position.x, position.y, position.z],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import create from 'zustand'
|
import create from 'zustand'
|
||||||
import { addLineHighlight, EditorView } from './editor/highlightextension'
|
import { addLineHighlight, EditorView } from './editor/highlightextension'
|
||||||
import { Program, abstractSyntaxTree } from './lang/abstractSyntaxTree'
|
import { Program, abstractSyntaxTree } from './lang/abstractSyntaxTree'
|
||||||
|
import { ProgramMemory } from './lang/executor'
|
||||||
import { recast } from './lang/recast'
|
import { recast } from './lang/recast'
|
||||||
import { lexer } from './lang/tokeniser'
|
import { lexer } from './lang/tokeniser'
|
||||||
import { Quaternion } from 'three'
|
import { Quaternion } from 'three'
|
||||||
|
|
||||||
export type Range = [number, number]
|
export type Range = [number, number]
|
||||||
|
|
||||||
type Plane = 'xy' | 'xz' | 'yz'
|
|
||||||
type PathToNode = (string | number)[]
|
type PathToNode = (string | number)[]
|
||||||
|
type Position = [number, number, number]
|
||||||
|
|
||||||
type GuiModes =
|
type GuiModes =
|
||||||
| {
|
| {
|
||||||
@ -18,6 +19,7 @@ type GuiModes =
|
|||||||
mode: 'sketch'
|
mode: 'sketch'
|
||||||
sketchMode: 'points'
|
sketchMode: 'points'
|
||||||
quaternion: Quaternion
|
quaternion: Quaternion
|
||||||
|
position: Position
|
||||||
id?: string
|
id?: string
|
||||||
pathToNode: PathToNode
|
pathToNode: PathToNode
|
||||||
}
|
}
|
||||||
@ -25,6 +27,7 @@ type GuiModes =
|
|||||||
mode: 'sketch'
|
mode: 'sketch'
|
||||||
sketchMode: 'sketchEdit'
|
sketchMode: 'sketchEdit'
|
||||||
quaternion: Quaternion
|
quaternion: Quaternion
|
||||||
|
position: Position
|
||||||
pathToNode: PathToNode
|
pathToNode: PathToNode
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
@ -35,6 +38,7 @@ type GuiModes =
|
|||||||
mode: 'canEditSketch'
|
mode: 'canEditSketch'
|
||||||
pathToNode: PathToNode
|
pathToNode: PathToNode
|
||||||
quaternion: Quaternion
|
quaternion: Quaternion
|
||||||
|
position: Position
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StoreState {
|
interface StoreState {
|
||||||
@ -62,6 +66,8 @@ interface StoreState {
|
|||||||
error: string
|
error: string
|
||||||
}
|
}
|
||||||
setError: (error?: string) => void
|
setError: (error?: string) => void
|
||||||
|
programMemory: ProgramMemory
|
||||||
|
setProgramMemory: (programMemory: ProgramMemory) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useStore = create<StoreState>()((set, get) => ({
|
export const useStore = create<StoreState>()((set, get) => ({
|
||||||
@ -123,4 +129,6 @@ export const useStore = create<StoreState>()((set, get) => ({
|
|||||||
setError: (error = '') => {
|
setError: (error = '') => {
|
||||||
set({ errorState: { isError: !!error, error } })
|
set({ errorState: { isError: !!error, error } })
|
||||||
},
|
},
|
||||||
|
programMemory: { root: {}, _sketch: [] },
|
||||||
|
setProgramMemory: (programMemory) => set({ programMemory }),
|
||||||
}))
|
}))
|
||||||
|
Reference in New Issue
Block a user