233 lines
8.7 KiB
JavaScript
233 lines
8.7 KiB
JavaScript
|
"use strict";
|
||
|
const common_vendor = require("../../common/vendor.js");
|
||
|
const _sfc_main = {
|
||
|
__name: "index",
|
||
|
setup(__props) {
|
||
|
const threeContainer = common_vendor.ref(null);
|
||
|
common_vendor.onMounted(() => {
|
||
|
const container = threeContainer.value;
|
||
|
const W = container.clientWidth, H = 400;
|
||
|
const scene = new common_vendor.Scene();
|
||
|
scene.background = new common_vendor.Color(16119285);
|
||
|
const camera = new common_vendor.PerspectiveCamera(60, W / H, 0.1, 1e3);
|
||
|
camera.position.set(0, 20, 30);
|
||
|
const renderer = new common_vendor.WebGLRenderer({
|
||
|
antialias: true
|
||
|
});
|
||
|
renderer.setSize(W, H);
|
||
|
renderer.shadowMap.enabled = true;
|
||
|
container.appendChild(renderer.domElement);
|
||
|
scene.add(new common_vendor.AmbientLight(16777215, 0.5));
|
||
|
const dirL = new common_vendor.DirectionalLight(16777215, 0.8);
|
||
|
dirL.position.set(-10, 20, 10);
|
||
|
dirL.castShadow = true;
|
||
|
scene.add(dirL);
|
||
|
const ground = new common_vendor.Mesh(
|
||
|
new common_vendor.BoxGeometry(50, 0.02, 50),
|
||
|
new common_vendor.MeshStandardMaterial({
|
||
|
color: 14540253
|
||
|
})
|
||
|
);
|
||
|
ground.position.y = -0.01;
|
||
|
ground.receiveShadow = true;
|
||
|
scene.add(ground);
|
||
|
const wallMat = new common_vendor.MeshStandardMaterial({
|
||
|
color: 16316664,
|
||
|
roughness: 0.7,
|
||
|
metalness: 0.1,
|
||
|
side: common_vendor.DoubleSide
|
||
|
});
|
||
|
const lintelMat = new common_vendor.MeshStandardMaterial({
|
||
|
color: 14737632,
|
||
|
roughness: 0.6,
|
||
|
metalness: 0.1
|
||
|
});
|
||
|
const doorMat = new common_vendor.MeshStandardMaterial({
|
||
|
color: 9127187,
|
||
|
roughness: 0.6,
|
||
|
metalness: 0.2
|
||
|
});
|
||
|
const bedFrameMat = new common_vendor.MeshStandardMaterial({
|
||
|
color: 5592405,
|
||
|
roughness: 0.5,
|
||
|
metalness: 0.8
|
||
|
});
|
||
|
const mattressMat = new common_vendor.MeshStandardMaterial({
|
||
|
color: 16777215,
|
||
|
roughness: 0.8,
|
||
|
metalness: 0.1
|
||
|
});
|
||
|
const tvMat = new common_vendor.MeshStandardMaterial({
|
||
|
color: 0,
|
||
|
roughness: 0.4,
|
||
|
metalness: 0.3
|
||
|
});
|
||
|
let selectedRoom = null;
|
||
|
function markOriginal(mesh) {
|
||
|
mesh.userData.originalMaterial = mesh.material.clone();
|
||
|
}
|
||
|
function createRoom({
|
||
|
w,
|
||
|
h,
|
||
|
d,
|
||
|
x,
|
||
|
z,
|
||
|
door
|
||
|
}) {
|
||
|
const room = new common_vendor.Group();
|
||
|
room.position.set(x, h / 2, z);
|
||
|
room.userData.isRoom = true;
|
||
|
room.userData.selected = false;
|
||
|
const planeH = new common_vendor.PlaneGeometry(w, h);
|
||
|
const planeD = new common_vendor.PlaneGeometry(d, h);
|
||
|
const upH = h - door.height - door.sill;
|
||
|
const upWall = new common_vendor.Mesh(new common_vendor.PlaneGeometry(w, upH), wallMat.clone());
|
||
|
upWall.position.set(0, door.height + door.sill + upH / 2 - h / 2, d / 2);
|
||
|
markOriginal(upWall);
|
||
|
room.add(upWall);
|
||
|
const sideW = (w - door.width) / 2;
|
||
|
const leftWall = new common_vendor.Mesh(new common_vendor.PlaneGeometry(sideW, door.height), wallMat.clone());
|
||
|
leftWall.position.set(-w / 2 + sideW / 2, door.sill + door.height / 2 - h / 2, d / 2);
|
||
|
markOriginal(leftWall);
|
||
|
room.add(leftWall);
|
||
|
const rightWall = leftWall.clone();
|
||
|
rightWall.position.x = w / 2 - sideW / 2;
|
||
|
markOriginal(rightWall);
|
||
|
room.add(rightWall);
|
||
|
const lintel = new common_vendor.Mesh(new common_vendor.BoxGeometry(door.width, door.lintelThk, 0.1), lintelMat.clone());
|
||
|
lintel.position.set(0, door.sill + door.height + door.lintelThk / 2 - h / 2, d / 2 + 0.05);
|
||
|
markOriginal(lintel);
|
||
|
room.add(lintel);
|
||
|
const doorGroup = new common_vendor.Group();
|
||
|
const doorMesh = new common_vendor.Mesh(new common_vendor.BoxGeometry(door.width, door.height, 0.05), doorMat.clone());
|
||
|
markOriginal(doorMesh);
|
||
|
doorMesh.position.set(door.width / 2, door.height / 2 - h / 2, 0);
|
||
|
doorGroup.add(doorMesh);
|
||
|
doorGroup.position.set(-w / 2 + sideW + 0.01, 0, d / 2 + 0.025);
|
||
|
doorGroup.userData.isDoor = true;
|
||
|
doorGroup.userData.open = false;
|
||
|
room.add(doorGroup);
|
||
|
const north = new common_vendor.Mesh(planeH, wallMat.clone());
|
||
|
north.position.set(0, 0, -d / 2);
|
||
|
north.rotation.y = Math.PI;
|
||
|
markOriginal(north);
|
||
|
room.add(north);
|
||
|
const east = new common_vendor.Mesh(planeD, wallMat.clone());
|
||
|
east.position.set(w / 2, 0, 0);
|
||
|
east.rotation.y = -Math.PI / 2;
|
||
|
markOriginal(east);
|
||
|
room.add(east);
|
||
|
const west = east.clone();
|
||
|
west.position.x = -w / 2;
|
||
|
west.rotation.y = Math.PI / 2;
|
||
|
markOriginal(west);
|
||
|
room.add(west);
|
||
|
const bedW = w * 0.6, bedH = 0.5, bedD = d * 0.4;
|
||
|
const bed = new common_vendor.Group();
|
||
|
bed.userData.isBed = true;
|
||
|
const frame = new common_vendor.Mesh(new common_vendor.BoxGeometry(bedW, 0.1, bedD), bedFrameMat.clone());
|
||
|
frame.position.y = -h / 2 + 0.05;
|
||
|
markOriginal(frame);
|
||
|
bed.add(frame);
|
||
|
const mat = new common_vendor.Mesh(new common_vendor.BoxGeometry(bedW * 0.95, bedH, bedD * 0.95), mattressMat.clone());
|
||
|
mat.position.y = -h / 2 + bedH / 2 + 0.05;
|
||
|
markOriginal(mat);
|
||
|
bed.add(mat);
|
||
|
bed.position.set(0, 0, d / 2 - bedD / 2 - 0.05);
|
||
|
room.add(bed);
|
||
|
const tvWidth = bedW * 0.6;
|
||
|
const tvHeight = tvWidth * 9 / 16;
|
||
|
const tv = new common_vendor.Mesh(new common_vendor.BoxGeometry(tvWidth, tvHeight, 0.05), tvMat.clone());
|
||
|
tv.userData.isTV = true;
|
||
|
markOriginal(tv);
|
||
|
tv.position.set(0, bedH + tvHeight / 2, -d / 2 + 0.05);
|
||
|
room.add(tv);
|
||
|
room.traverse((o) => {
|
||
|
if (o.isMesh) {
|
||
|
o.castShadow = true;
|
||
|
o.receiveShadow = true;
|
||
|
}
|
||
|
});
|
||
|
return room;
|
||
|
}
|
||
|
const building = new common_vendor.Group();
|
||
|
const cols = 5, rows = 4, sx = 6, sz = 8;
|
||
|
for (let i = 0; i < 20; i++) {
|
||
|
const col = i % cols, row = Math.floor(i / cols);
|
||
|
const x = -((cols - 1) * sx) / 2 + col * sx;
|
||
|
const z = (rows - 1) * sz / 2 - row * sz;
|
||
|
building.add(createRoom({
|
||
|
w: 4,
|
||
|
h: 3,
|
||
|
d: 5,
|
||
|
x,
|
||
|
z,
|
||
|
door: {
|
||
|
width: 1,
|
||
|
height: 2,
|
||
|
sill: 0.1,
|
||
|
lintelThk: 0.2
|
||
|
}
|
||
|
}));
|
||
|
}
|
||
|
scene.add(building);
|
||
|
const controls = new common_vendor.OrbitControls(camera, renderer.domElement);
|
||
|
controls.enableDamping = true;
|
||
|
const ray = new common_vendor.Raycaster(), mouse = new common_vendor.Vector2();
|
||
|
renderer.domElement.addEventListener("click", (e) => {
|
||
|
const rect = renderer.domElement.getBoundingClientRect();
|
||
|
mouse.x = (e.clientX - rect.left) / rect.width * 2 - 1;
|
||
|
mouse.y = -((e.clientY - rect.top) / rect.height) * 2 + 1;
|
||
|
ray.setFromCamera(mouse, camera);
|
||
|
const hits = ray.intersectObjects(building.children, true);
|
||
|
if (!hits.length)
|
||
|
return;
|
||
|
let obj = hits[0].object;
|
||
|
const doorGrp = obj.userData.isDoor ? obj : obj.parent.userData.isDoor ? obj.parent : null;
|
||
|
if (doorGrp) {
|
||
|
const open = !doorGrp.userData.open;
|
||
|
doorGrp.rotation.y = open ? -Math.PI / 2 : 0;
|
||
|
doorGrp.userData.open = open;
|
||
|
return;
|
||
|
}
|
||
|
let tgt = hits[0].object;
|
||
|
while (tgt && !tgt.userData.isRoom)
|
||
|
tgt = tgt.parent;
|
||
|
if (!tgt)
|
||
|
return;
|
||
|
if (selectedRoom && selectedRoom !== tgt) {
|
||
|
selectedRoom.userData.selected = false;
|
||
|
selectedRoom.traverse((n) => {
|
||
|
if (n.isMesh && n.userData.originalMaterial) {
|
||
|
n.material = n.userData.originalMaterial.clone();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
const sel = !tgt.userData.selected;
|
||
|
tgt.userData.selected = sel;
|
||
|
tgt.traverse((n) => {
|
||
|
if (n.isMesh && n.userData.originalMaterial) {
|
||
|
let matClone = n.userData.originalMaterial.clone();
|
||
|
if (sel && !n.userData.isTV && !n.userData.isDoor)
|
||
|
matClone.color.set(3373055);
|
||
|
n.material = matClone;
|
||
|
}
|
||
|
});
|
||
|
selectedRoom = sel ? tgt : null;
|
||
|
});
|
||
|
const animate = () => {
|
||
|
requestAnimationFrame(animate);
|
||
|
controls.update();
|
||
|
renderer.render(scene, camera);
|
||
|
};
|
||
|
animate();
|
||
|
});
|
||
|
return (_ctx, _cache) => {
|
||
|
return {};
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-a3704cdf"]]);
|
||
|
wx.createPage(MiniProgramPage);
|
||
|
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/map/index.js.map
|