Skip to content

Commit

Permalink
feat: points draw wall
Browse files Browse the repository at this point in the history
  • Loading branch information
gong9 committed Oct 20, 2023
1 parent a0de0e3 commit 9ef1078
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 8 deletions.
Binary file added src/assets/wall.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 13 additions & 2 deletions src/hooks/useCreateLine.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { useEffect, useRef } from 'react'
import { useThree } from '@react-three/fiber'
import { Line2, LineGeometry, LineMaterial } from 'three-stdlib'
import { BufferAttribute, BufferGeometry, Points, PointsMaterial } from 'three'
import { BufferAttribute, BufferGeometry, Points, PointsMaterial, Vector3 } from 'three'

import useModeStore from '@/store/mode'
import { createBoxGeometryByPoints } from '@/utils/lineDerivation'

/**
* init draw line
* @param scene
*/
const useCreateLine = () => {
const pointsRef = useRef<Float32Array>(new Float32Array(3))
const pointsArrayRef = useRef<Vector3[]>([])
const geometryRef = useRef<LineGeometry | null>(null)
const pointRef = useRef<Points | null>(null)
const countRef = useRef<number>(0)
Expand Down Expand Up @@ -48,15 +50,24 @@ const useCreateLine = () => {
if (!drawline)
return

pointsArrayRef.current.push(new Vector3(x, y, z))

if (countRef.current === 0) {
pointsRef.current = new Float32Array([x, y, z])
drawPoint(x, y, z)
}

else { pointsRef.current = new Float32Array([...pointsRef.current, x, y, z]) }
else {
pointsRef.current = new Float32Array([...pointsRef.current, x, y, z])
}

countRef.current += 1

if (countRef.current >= 2) {
const box = createBoxGeometryByPoints(pointsArrayRef.current[countRef.current - 2], pointsArrayRef.current[countRef.current - 1])
scene.add(box)
}

if (geometryRef.current && lineRef.current) {
scene.remove(lineRef.current)

Expand Down
6 changes: 5 additions & 1 deletion src/pages/Editor/canvas/components/RenderMesh.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { FC } from 'react'
import { memo, useEffect, useRef, useState } from 'react'
import isEqual from 'react-fast-compare'
import type { Box3, Vector3 } from 'three'
import { DoubleSide, TextureLoader } from 'three'
import { DoubleSide, RepeatWrapping, TextureLoader } from 'three'

import SelectdCube, { CubeType } from './Selected'
import useCreateLine from '@/hooks/useCreateLine'
Expand All @@ -11,6 +11,10 @@ import cementRoad from '@/assets/cementRoad.jpg'

const texture = new TextureLoader().load(cementRoad)

texture.wrapS = RepeatWrapping
texture.wrapT = RepeatWrapping
texture.repeat.set(10, 10)

interface RenderMeshProps {
mesh: MeshType
}
Expand Down
3 changes: 1 addition & 2 deletions src/pages/Editor/canvas/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@
}

.drawline {
cursor: url('../../../../public/image/mouse.ico'),
default;
cursor: url('../../../../public/image/mouse.ico') 0 30, auto;
}
4 changes: 2 additions & 2 deletions src/pages/Editor/left/presets.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const presets = {
planeGeometry: {
width: 50,
height: 50,
width: 100,
height: 100,
widthSegments: 1,
heightSegments: 1,
},
Expand Down
2 changes: 1 addition & 1 deletion src/store/three.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface ThreeStoreStates {
}

interface ThreeStoreActions {
setCurrentScene: (scene: Scene) => void
setCurrentScene: (scene: Scene) => void // TODOS: 貌似没有更新
setCurrentMainCamera: (camera: Camera) => void
setCurrentControls: (controls: OrbitControls) => void
}
Expand Down
49 changes: 49 additions & 0 deletions src/utils/lineDerivation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { BoxGeometry, DoubleSide, Mesh, MeshBasicMaterial, Quaternion, RepeatWrapping, TextureLoader, Vector3 } from 'three'
import wall from '@/assets/wall.jpg'

/**
* create box geometry by two points
* @param a
* @param b
* @param height
* @param depth
*/
export const createBoxGeometryByPoints = (a: Vector3, b: Vector3, height = 1, depth = 0.2) => {
// step 1: get position
const width = a.distanceTo(b)
const box = new BoxGeometry(width, height, depth)

const texture = new TextureLoader().load(wall)
texture.wrapS = RepeatWrapping
texture.wrapT = RepeatWrapping

texture.repeat.set(Math.ceil(width), 1)

const material = new MeshBasicMaterial({ map: texture, side: DoubleSide, color: '#ac7c6a' })
const mesh = new Mesh(box, material)

// get center point
const midpoint = new Vector3().addVectors(a, b).multiplyScalar(0.5)

mesh.position.x = midpoint.x
mesh.position.y = midpoint.y + height / 2
mesh.position.z = midpoint.z

// step 2: rotate box
const direction = new Vector3()
direction.subVectors(a, b)
direction.normalize()

const axis = new Vector3(0, 1, 0) // axis
const angle = new Vector3(1, 0, 0).angleTo(direction)

const quaternion = new Quaternion().setFromAxisAngle(axis, angle)
const newDirection = new Vector3(1, 0, 0).applyQuaternion(quaternion)

if (!newDirection.angleTo(direction))
mesh.rotateOnAxis(axis, angle)
else
mesh.rotateOnAxis(axis, -angle)

return mesh
}

0 comments on commit 9ef1078

Please sign in to comment.