Skip to content

Commit

Permalink
- 增加方向以及不允许空缺
Browse files Browse the repository at this point in the history
  • Loading branch information
linyisonger committed Sep 13, 2024
1 parent 9502361 commit 4abff0c
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 15 deletions.
173 changes: 158 additions & 15 deletions 075.Three.js 观察物体.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,46 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./assets/global.css">
<style>
.panel-container {
position: absolute;
top: 0;
left: 0;
height: 200px;
width: 100%;
background-color: rgba(255, 255, 255, .8);
padding: 20px;
box-sizing: border-box;
}

.mode-switch {
display: inline-flex;
overflow: hidden;
height: 32px;
border-radius: 6px;
background-color: #ccc;
}

.mode-switch .mode-switch-item {
display: inline-block;
padding: 0 8px;
line-height: 32px;
font-size: 12px;
background-color: transparent;
cursor: pointer;
}

.mode-switch .mode-switch-item.active {
background-color: #88ccee;
}

.mode-switch .mode-switch-item.del.active {
background-color: #cc3333;
}
</style>
</head>

<body>

<script type="importmap">
{
"imports": {
Expand All @@ -19,14 +55,39 @@
}
</script>

<div class="panel-container">
<div class="mode-switch">
<div class="mode-switch-item new">新增模式</div>
<div class="mode-switch-item del">删除模式</div>
</div>
</div>


<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

let newModeDom = document.querySelector('.mode-switch-item.new')
let delModeDom = document.querySelector('.mode-switch-item.del')

let isNew = true;
newModeDom.addEventListener('click', () => {
isNew = true;
newModeDom.classList.add('active')
delModeDom.classList.remove('active')
})
delModeDom.addEventListener('click', () => {
isNew = false;
delModeDom.classList.add('active')
newModeDom.classList.remove('active')
})
newModeDom.click()

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x88ccee);
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(-5.5, 5, -5.5);
camera.position.set(-10.5, 5, -10.5);

const renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
Expand Down Expand Up @@ -56,6 +117,9 @@
// 4 x 4
const MaximumSize = 4;

// 方块存储
const cubeMap = {}

for (let x = 0; x < MaximumSize; x++) {
for (let z = 0; z < MaximumSize; z++) {
console.log(x, z);
Expand All @@ -70,6 +134,28 @@
}
}

const gltfLoader = new GLTFLoader().setPath('./assets/observing-objects/');
gltfLoader.load('left.glb', (gltf) => {
gltf.scene.position.x = 4.5;
gltf.scene.position.y = 1.5;
gltf.scene.position.z = -0.5;
scene.add(gltf.scene);
})
gltfLoader.load('up.glb', (gltf) => {
gltf.scene.position.x = 0.5;
gltf.scene.position.y = 4.5;
gltf.scene.position.z = -0.5;
scene.add(gltf.scene);
})
gltfLoader.load('front.glb', (gltf) => {
gltf.scene.position.x = 0.5;
gltf.scene.position.y = 0;
gltf.scene.position.z = -4.5;
scene.add(gltf.scene);
})



// 控制器
let controls = new OrbitControls(camera, renderer.domElement);
controls.screenSpacePanning = true;
Expand All @@ -81,7 +167,7 @@
//获取鼠标坐标 处理点击某个模型的事件
let mouse = new THREE.Vector2();
let raycaster = new THREE.Raycaster();

// 模型点击事件
function onmodelclick(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
Expand All @@ -98,21 +184,42 @@
let lastObjectNormal = lastObject.normal // 点击的方向
let lastObjectPosition = lastObject.object.position // 物体的位置
console.log(lastObjectNormal, lastObjectPosition);
let x = lastObjectNormal.x + lastObjectPosition.x
let y = lastObjectNormal.y + lastObjectPosition.y
let z = lastObjectNormal.z + lastObjectPosition.z
let isPlane = lastObject.object.name.startsWith('plane');
let cube = createCube();
cube.position.x = x
cube.position.y = y - (isPlane ? .5 : 0)
cube.position.z = z
cube.name = `cube(${x, y, z})`
scene.add(cube)

if (isNew) {
let x = lastObjectNormal.x + lastObjectPosition.x
let y = lastObjectNormal.y + lastObjectPosition.y - (isPlane ? .5 : 0)
let z = lastObjectNormal.z + lastObjectPosition.z
let cube = createCube();
console.log(x, y, z);
let checkUnderHasCudeRes = checkUnderHasCude(x, y, z)

if (isRange(x, y, z) && checkUnderHasCudeRes) {
x = checkUnderHasCudeRes.x
y = checkUnderHasCudeRes.y
z = checkUnderHasCudeRes.z

cube.position.x = x
cube.position.y = y
cube.position.z = z

let standardKey = positionConversion(x, y, z)
cubeMap[standardKey] = cube
cube.name = `cube(${x},${y},${z})`
scene.add(cube)
}
else {
console.log('不能添加');
}
}
else if (!isPlane) {
scene.remove(lastObject.object)
console.log('需要删除的物体', lastObject);
}
}

}
window.addEventListener("click", onmodelclick);

// 是否在范围内
function isRange(x, y, z) {
let maxX = MaximumSize / 2;
Expand All @@ -121,17 +228,51 @@
let minZ = -MaximumSize / 2;
let maxY = MaximumSize;
let minY = 0;

if (y > maxY) return false
if (y < minY) return false
if (x >= maxX) return false;
if (x < minX) return false;
if (z >= maxZ) return false;
if (z < minZ) return false;
return true;
}
// 检测是否下面有物体
function checkUnderHasCude(x, y, z) {
let standardKey = positionConversion(x, y, z)
let standerdY = +standardKey.split(',')[1]
console.log("standerdY", standerdY);
for (let i = 0; i <= standerdY; i++) {
let tmpStandardKey = positionConversion(x, i, z)
if (!cubeMap[tmpStandardKey]) {
return {
x,
y: y - standerdY + i,
z
};
}
}
return false
}

// 坐标处理 便于存储
function positionConversion(x, y, z) {
y = Math.floor(y)
x = x + MaximumSize / 2;
z = z + MaximumSize / 2;
return `${x},${y},${z}`
console.log(x, y, z);
}
// 创建方块
function createCube() {
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = cubeMaterial || new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
cube.receiveShadow = true
cube.castShadow = true;
return cube
}


// 渲染动画
function animate() {
renderer.render(scene, camera);
requestAnimationFrame(animate);
Expand All @@ -142,6 +283,8 @@
}
animate();
</script>


</body>

</html>
Binary file added assets/observing-objects/front.glb
Binary file not shown.
Binary file added assets/observing-objects/left.glb
Binary file not shown.
Binary file added assets/observing-objects/up.glb
Binary file not shown.

0 comments on commit 4abff0c

Please sign in to comment.