port over to quanternions

This commit is contained in:
Kurt Hutten IrevDev
2022-12-23 07:37:42 +11:00
parent 6abc0d2798
commit 07a40cdd11
6 changed files with 112 additions and 44 deletions

View File

@ -28,6 +28,7 @@ export const Toolbar = () => {
sketchMode: 'sketchEdit',
pathToNode: guiMode.pathToNode,
axis: guiMode.axis,
quaternion: guiMode.quaternion,
})
}}
className="border m-1 px-1 rounded"
@ -51,10 +52,13 @@ export const Toolbar = () => {
className={`border m-1 px-1 rounded ${
guiMode.sketchMode === 'points' && 'bg-gray-400'
}`}
onClick={() => setGuiMode({
...guiMode,
sketchMode: guiMode.sketchMode === 'points' ? 'sketchEdit' :'points',
})}
onClick={() =>
setGuiMode({
...guiMode,
sketchMode:
guiMode.sketchMode === 'points' ? 'sketchEdit' : 'points',
})
}
>
LineTo{guiMode.sketchMode === 'points' && '✅'}
</button>

View File

@ -1,9 +1,10 @@
import { useState } from 'react'
import { DoubleSide } from 'three'
import { DoubleSide, Vector3 } from 'three'
import { useStore } from '../useStore'
import { Intersection } from '@react-three/fiber'
import { Text } from '@react-three/drei'
import { addSketchTo, Program } from '../lang/abstractSyntaxTree'
import { Quaternion } from 'three'
const opacity = 0.1
@ -52,12 +53,19 @@ export const BasePlanes = () => {
body: [],
}
const axis = axisIndex === 0 ? 'xy' : axisIndex === 1 ? 'xz' : 'yz'
const quaternion = new Quaternion()
if (axisIndex === 1) {
quaternion.setFromAxisAngle(new Vector3(1, 0, 0), Math.PI / 2)
} else if (axisIndex === 2) {
quaternion.setFromAxisAngle(new Vector3(0, 1, 0), Math.PI / 2)
}
const { modifiedAst, id, pathToNode } = addSketchTo(_ast, axis)
setGuiMode({
mode: 'sketch',
sketchMode: 'sketchEdit',
axis,
quaternion,
pathToNode,
})
@ -88,10 +96,20 @@ export const BasePlanes = () => {
transparent
opacity={opacity + (axisIndex === index ? 0.3 : 0)}
/>
<Text fontSize={1} color="#555" position={[1, 1, 0.01]} font={'/roboto.woff'}>
<Text
fontSize={1}
color="#555"
position={[1, 1, 0.01]}
font={'/roboto.woff'}
>
{index === 0 ? 'xy' : index === 1 ? 'xz' : 'yz'}
</Text>
<Text fontSize={1} color="#555" position={[1, 1, -0.01]} font={'/roboto.woff'}>
<Text
fontSize={1}
color="#555"
position={[1, 1, -0.01]}
font={'/roboto.woff'}
>
{index === 0 ? 'xy' : index === 1 ? 'xz' : 'yz'}
</Text>
</mesh>

View File

@ -10,7 +10,7 @@ import { BufferGeometry } from 'three'
import { useStore } from '../useStore'
import { isOverlapping } from '../lib/utils'
import { LineGeos } from '../lang/engine'
import { Vector3 } from 'three'
import { Vector3, DoubleSide, Quaternion, Vector2 } from 'three'
function useHeightlight(sourceRange: [number, number]) {
const { selectionRange, guiMode, setGuiMode, ast } = useStore((s) => ({
@ -29,13 +29,25 @@ function useHeightlight(sourceRange: [number, number]) {
if (shouldHighlight && guiMode.mode === 'default' && ast) {
const pathToNode = getNodePathFromSourceRange(ast, sourceRange)
const piper = getNodeFromPath(ast, pathToNode, 'PipeExpression')
const quaternion = new Quaternion()
if (piper.type === 'PipeExpression') {
const rotateName = piper?.body?.[1]?.callee?.name
const rotateValue = piper?.body?.[1]?.arguments[0].value
let rotateAxis = new Vector3(1, 0, 0)
if (rotateName === 'ry') {
rotateAxis = new Vector3(0, 1, 0)
} else if (rotateName === 'rz') {
rotateAxis = new Vector3(0, 0, 1)
}
quaternion.setFromAxisAngle(rotateAxis, (Math.PI * rotateValue) / 180)
}
const axis =
piper.type !== 'PipeExpression'
? 'xy'
: piper?.body?.[1]?.callee?.name === 'rx'
? 'xz'
: 'yz'
setGuiMode({ mode: 'canEditSketch', pathToNode, axis })
setGuiMode({ mode: 'canEditSketch', pathToNode, axis, quaternion }) // TODO needs fix
setDidSetCanEdit(true)
} else if (
!shouldHighlight &&
@ -122,7 +134,9 @@ function MovingSphere({
editorCursor: boolean
}) {
const ref = useRef<BufferGeometry | undefined>() as any
const detectionPlaneRef = useRef<BufferGeometry | undefined>() as any
const lastPointerRef = useRef<Vector3>(new Vector3())
const point2DRef = useRef<Vector2>(new Vector2())
const [hovered, setHover] = useState(false)
const [isMouseDown, setIsMouseDown] = useState(false)
@ -141,7 +155,6 @@ function MovingSphere({
const [xArg, yArg] = callExpression?.arguments || []
const x = xArg?.type === 'Literal' ? xArg.value : -1
const y = yArg?.type === 'Literal' ? yArg.value : -1
console.log(callExpression)
return {
originalXY: [x, y],
}
@ -155,11 +168,11 @@ function MovingSphere({
const handleMouseUp = () => {
if (isMouseDown && ast) {
const thePath = getNodePathFromSourceRange(ast, sourceRange)
const theNewPoints: [number, number] = [
roundOff(lastPointerRef.current.x, 2),
roundOff(lastPointerRef.current.y, 2),
let [x, y] = [
roundOff(point2DRef.current.x, 2),
roundOff(point2DRef.current.y, 2),
]
console.log('theNewPoints', theNewPoints)
let theNewPoints: [number, number] = [x, y]
const { modifiedAst } = changeArguments(ast, thePath, theNewPoints)
updateAst(modifiedAst)
ref.current.position.set(0, 0, 0)
@ -172,6 +185,14 @@ function MovingSphere({
}
}, [isMouseDown, ast])
let clickDetectPlaneQuaternion = new Quaternion()
if (
guiMode.mode === 'canEditSketch' ||
(guiMode.mode === 'sketch' && guiMode.sketchMode === 'sketchEdit')
) {
clickDetectPlaneQuaternion = guiMode.quaternion.clone()
}
return (
<>
<mesh
@ -193,9 +214,23 @@ function MovingSphere({
</mesh>
{isMouseDown && (
<mesh
position={[0, 0, 0.05]}
position={[0, 0, -0.05]}
quaternion={clickDetectPlaneQuaternion}
onPointerMove={(a) => {
const point = a.point
const transformedPoint = point.clone()
let inverseQuaternion = new Quaternion()
if (
guiMode.mode === 'canEditSketch' ||
(guiMode.mode === 'sketch' && guiMode.sketchMode === 'sketchEdit')
) {
inverseQuaternion = guiMode.quaternion.clone()
}
inverseQuaternion = inverseQuaternion.invert()
transformedPoint.applyQuaternion(inverseQuaternion)
point2DRef.current.set(transformedPoint.x, transformedPoint.y)
if (
lastPointerRef.current.x === 0 &&
lastPointerRef.current.y === 0 &&
@ -223,8 +258,13 @@ function MovingSphere({
}}
name="my-mesh"
>
<planeGeometry args={[50, 50]} />
<meshStandardMaterial color="blue" transparent opacity={0.2} />
<planeGeometry args={[50, 50]} ref={detectionPlaneRef} />
<meshStandardMaterial
side={DoubleSide}
color="blue"
transparent
opacity={0}
/>
</mesh>
)}
</>

View File

@ -1,5 +1,5 @@
import { useStore } from '../useStore'
import { DoubleSide } from 'three'
import { DoubleSide, Vector3, Quaternion } from 'three'
import { addLine, Program } from '../lang/abstractSyntaxTree'
export const SketchPlane = () => {
@ -14,28 +14,27 @@ export const SketchPlane = () => {
if (guiMode.mode !== 'sketch') {
return null
}
if (guiMode.sketchMode !== 'points' && guiMode.sketchMode !== 'sketchEdit' ) {
if (guiMode.sketchMode !== 'points' && guiMode.sketchMode !== 'sketchEdit') {
return null
}
const sketchGridName = 'sketchGrid'
const ninety = Math.PI / 2
const gridRotation: [number, number, number] = [0, 0, 0]
const clickDetectPlaneRotation: [number, number, number] = [0, 0, 0]
if (guiMode.axis === 'xy') {
gridRotation[0] = ninety
} else if (guiMode.axis === 'xz') {
clickDetectPlaneRotation[0] = ninety
} else if (guiMode.axis === 'yz') {
gridRotation[2] = ninety
clickDetectPlaneRotation[1] = ninety
}
let clickDetectQuaternion = guiMode.quaternion.clone()
let temp = new Quaternion().setFromAxisAngle(
new Vector3(1, 0, 0),
Math.PI / 2
)
const gridQuaternion = new Quaternion().multiplyQuaternions(
guiMode.quaternion,
temp
)
return (
<>
<mesh
rotation={clickDetectPlaneRotation}
quaternion={clickDetectQuaternion}
name={sketchGridName}
onClick={(e) => {
if (guiMode.sketchMode !== 'points') {
@ -44,7 +43,12 @@ export const SketchPlane = () => {
const sketchGridIntersection = e.intersections.find(
({ object }) => object.name === sketchGridName
)
const point = roundy(sketchGridIntersection?.point)
const inverseQuaternion = clickDetectQuaternion.clone().invert()
let transformedPoint = sketchGridIntersection?.point.clone()
if (transformedPoint)
transformedPoint.applyQuaternion(inverseQuaternion)
const point = roundy(transformedPoint)
let _ast: Program = ast
? ast
: {
@ -53,12 +57,7 @@ export const SketchPlane = () => {
end: 0,
body: [],
}
let addLinePoint: [number, number] = [point.x, point.y]
if (guiMode.axis === 'xz') {
addLinePoint = [point.x, point.z]
} else if (guiMode.axis === 'yz') {
addLinePoint = [point.z, point.y]
}
const addLinePoint: [number, number] = [point.x, point.y]
const { modifiedAst } = addLine(
_ast,
guiMode.pathToNode,
@ -75,7 +74,10 @@ export const SketchPlane = () => {
transparent
/>
</mesh>
<gridHelper args={[30, 40, 'blue', 'hotpink']} rotation={gridRotation} />
<gridHelper
args={[30, 40, 'blue', 'hotpink']}
quaternion={gridQuaternion}
/>
</>
)
}

View File

@ -1016,8 +1016,8 @@ export function addSketchTo(
{
type: 'Literal',
...dumbyStartend,
value: axis === 'yz' ? -90 : 90,
raw: axis === 'yz' ? '-90' : '90',
value: axis === 'yz' ? 90 : 90,
raw: axis === 'yz' ? '90' : '90',
},
{
type: 'PipeSubstitution',

View File

@ -3,6 +3,7 @@ import { addLineHighlight, EditorView } from './editor/highlightextension'
import { Program, abstractSyntaxTree } from './lang/abstractSyntaxTree'
import { recast } from './lang/recast'
import { lexer } from './lang/tokeniser'
import { Quaternion } from 'three'
export type Range = [number, number]
@ -17,6 +18,7 @@ type GuiModes =
mode: 'sketch'
sketchMode: 'points'
axis: Plane
quaternion: Quaternion
id?: string
pathToNode: PathToNode
}
@ -24,8 +26,9 @@ type GuiModes =
mode: 'sketch'
sketchMode: 'sketchEdit'
axis: Plane
quaternion: Quaternion
pathToNode: PathToNode
}
}
| {
mode: 'sketch'
sketchMode: 'selectFace'
@ -34,7 +37,8 @@ type GuiModes =
mode: 'canEditSketch'
pathToNode: PathToNode
axis: Plane
}
quaternion: Quaternion
}
interface StoreState {
editorView: EditorView | null
@ -121,5 +125,5 @@ export const useStore = create<StoreState>()((set, get) => ({
},
setError: (error = '') => {
set({ errorState: { isError: !!error, error } })
}
},
}))