<!DOCTYPE html>
<html lang="fa">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>3D House Map</title>
<style>
html,body{
margin:0;
width:100%;
height:100%;
overflow:hidden;
background:#111;
font-family:Arial;
}
canvas{
display:block;
}
#loading{
position:fixed;
inset:0;
z-index:100;
display:flex;
align-items:center;
justify-content:center;
background:#111;
color:white;
font-size:25px;
}
#hud{
position:fixed;
left:15px;
top:15px;
z-index:20;
color:white;
background:rgba(0,0,0,.55);
padding:12px 16px;
border-radius:12px;
line-height:1.8;
user-select:none;
}
#cross{
position:fixed;
left:50%;
top:50%;
width:5px;
height:5px;
border-radius:50%;
background:white;
transform:translate(-50%,-50%);
z-index:15;
}
</style>
</head>
<body>
<div id="loading">در حال ساخت مپ...</div>
<div id="hud">
<b>3D HOUSE</b><br>
WASD حرکت<br>
Shift دویدن<br>
Space پرش<br>
V اول شخص / سوم شخص<br>
E در<br>
کلیک چپ ضربه<br>
F لگد
</div>
<div id="cross"></div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script>
/* =========================================================
ENGINE
========================================================= */
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x87a9c4);
scene.fog = new THREE.Fog(
0x87a9c4,
45,
130
);
const camera = new THREE.PerspectiveCamera(
70,
innerWidth/innerHeight,
.05,
250
);
const renderer = new THREE.WebGLRenderer({
antialias:true,
powerPreference:"high-performance"
});
renderer.setSize(
innerWidth,
innerHeight
);
renderer.setPixelRatio(
Math.min(devicePixelRatio,1.6)
);
renderer.shadowMap.enabled=true;
renderer.shadowMap.type=THREE.PCFSoftShadowMap;
renderer.outputColorSpace=THREE.SRGBColorSpace;
renderer.toneMapping=THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure=1.1;
document.body.appendChild(
renderer.domElement
);
/* =========================================================
MATERIALS
========================================================= */
function M(color,roughness=.8,metalness=0){
return new THREE.MeshStandardMaterial({
color:color,
roughness:roughness,
metalness:metalness
});
}
const wall=M(0xd8d0c4,.9);
const wallInside=M(0xe4ded3,.95);
const floorWood=M(0x694a31,.75);
const floorTile=M(0xbfc3c5,.7);
const floorCarpet=M(0x3d3c3a,1);
const roof=M(0x3a3d42,.9);
const dark=M(0x16191d,.35,.7);
const metal=M(0x565b60,.3,.85);
const white=M(0xe8e7e1,.4);
const black=M(0x08090b,.25,.5);
const glass=new THREE.MeshPhysicalMaterial({
color:0x87b9d8,
roughness:.08,
metalness:.1,
transmission:.15,
transparent:true,
opacity:.55
});
const wood=M(0x69442a,.7);
const green=M(0x33483a,.9);
/* =========================================================
HELPERS
========================================================= */
function box(
x,y,z,
sx,sy,sz,
material,
parent=scene
){
const mesh=new THREE.Mesh(
new THREE.BoxGeometry(
sx,sy,sz
),
material
);
mesh.position.set(
x,y,z
);
mesh.castShadow=true;
mesh.receiveShadow=true;
parent.add(mesh);
return mesh;
}
function cyl(
x,y,z,
r,h,
material,
parent=scene,
seg=24
){
const mesh=new THREE.Mesh(
new THREE.CylinderGeometry(
r,r,h,seg
),
material
);
mesh.position.set(
x,y,z
);
mesh.castShadow=true;
mesh.receiveShadow=true;
parent.add(mesh);
return mesh;
}
function sphere(
x,y,z,
r,
material,
parent=scene
){
const mesh=new THREE.Mesh(
new THREE.SphereGeometry(
r,24,16
),
material
);
mesh.position.set(
x,y,z
);
mesh.castShadow=true;
mesh.receiveShadow=true;
parent.add(mesh);
return mesh;
}
/* =========================================================
LIGHT
========================================================= */
scene.add(
new THREE.HemisphereLight(
0xd8edff,
0x50463d,
1.5
)
);
const sun=new THREE.DirectionalLight(
0xffe9c7,
3
);
sun.position.set(
-35,
45,
25
);
sun.castShadow=true;
sun.shadow.mapSize.set(
2048,
2048
);
sun.shadow.camera.left=-70;
sun.shadow.camera.right=70;
sun.shadow.camera.top=70;
sun.shadow.camera.bottom=-70;
scene.add(sun);
function lamp(x,y,z,intensity=20){
const light=new THREE.PointLight(
0xffdca7,
intensity,
17
);
light.position.set(
x,y,z
);
light.castShadow=true;
scene.add(light);
const shade=cyl(
x,
y-.15,
z,
.25,
.15,
white
);
return light;
}
/* =========================================================
WORLD
========================================================= */
const world=new THREE.Group();
scene.add(world);
/*
خانه:
بیرون:
X = -30 تا +30
Z = -22 تا +22
داخل:
┌───────────────┬──────────────┐
│ اتاق خواب │ حمام │
│ │ │
├───────────────┼──────────────┤
│ │ │
│ راهرو │ پذیرایی │
│ │ │
├───────────────┤ │
│ کامپیوتر │ آشپزخانه │
│ │ │
└───────────────┴──────────────┘
*/
/* =========================================================
GROUND OUTSIDE
========================================================= */
box(
0,-.35,0,
100,.5,100,
M(0x596057,1)
);
/* driveway */
box(
0,-.05,30,
10,.12,28,
M(0x424448,1)
);
/* road */
box(
0,-.02,48,
100,.15,16,
M(0x292b2e,1)
);
/* road lines */
for(let x=-45;x<45;x+=10){
box(
x,.07,48,
5,.03,.18,
white
);
}
/* =========================================================
HOUSE FLOOR
========================================================= */
box(
0,0,0,
42,.25,32,
floorWood
);
/* carpet zones */
box(
-13,.14,9,
14,.04,10,
floorCarpet
);
box(
11,.14,7,
17,.04,12,
floorCarpet
);
/* bathroom floor */
box(
12,.16,-10,
14,.05,9,
floorTile
);
/* =========================================================
OUTER WALLS
========================================================= */
const H=6;
/* left */
box(
-21,H/2,0,
.4,H,32,
wall
);
/* right */
box(
21,H/2,0,
.4,H,32,
wall
);
/* back */
box(
0,H/2,-16,
42,H,.4,
wall
);
/*
front wall is split to make entrance
*/
box(
-14,H/2,16,
14,H,.4,
wall
);
box(
14,H/2,16,
14,H,.4,
wall
);
/* entrance top */
box(
0,5.2,16,
14,1.6,.4,
wall
);
/* =========================================================
ROOF
========================================================= */
const roofGroup=new THREE.Group();
scene.add(roofGroup);
/* flat ceiling */
box(
0,6.15,0,
42,.45,32,
roof
);
/* roof upper layer */
box(
0,6.65,0,
44,.4,34,
roof
);
/* roof edges */
box(
-22,6.6,0,
.5,1,35,
roof
);
box(
22,6.6,0,
.5,1,35,
roof
);
box(
0,6.6,-17,
44,1,.5,
roof
);
box(
0,6.6,17,
44,1,.5,
roof
);
/* =========================================================
INTERNAL WALLS
========================================================= */
/* computer room */
box(
-7,3,-2,
.3,6,28,
wallInside
);
/* bedroom separation */
box(
7,3,9,
28,.3,6,
wallInside
);
/* bathroom back */
box(
14,3,-12,
14,.3,8,
wallInside
);
/* bathroom left/right */
box(
7,3,-10,
.3,6,12,
wallInside
);
box(
21,3,-10,
.3,6,12,
wallInside
);
/* =========================================================
DOORS
========================================================= */
function door(x,z,w=2.5){
const g=new THREE.Group();
g.position.set(
x,
0,
z
);
const d=box(
0,
2,
0,
w,
4,
.18,
wood,
g
);
const handle=cyl(
w/2-.35,
2,
-.15,
.07,
.1,
metal,
g,
16
);
handle.rotation.x=Math.PI/2;
scene.add(g);
return g;
}
const frontDoor=door(
0,
16,
3
);
/* bedroom door */
const bedroomDoor=door(
4,
9,
2.5
);
/* bathroom door */
const bathroomDoor=door(
7,
-7,
2.5
);
/* =========================================================
WINDOWS
========================================================= */
function windowObj(
x,y,z,
sx,sy,sz
){
box(
x,y,z,
sx,sy,sz,
glass
);
/* frame */
box(
x-sx/2,
y,
z,
.12,
sy+.2,
.12,
dark
);
box(
x+sx/2,
y,
z,
.12,
sy+.2,
.12,
dark
);
box(
x,
y-sy/2,
z,
sx+.2,
.12,
.12,
dark
);
box(
x,
y+sy/2,
z,
sx+.2,
.12,
.12,
dark
);
}
/* living windows */
windowObj(
20.75,
3.4,
5,
.1,
4,
7
);
/* bedroom window */
windowObj(
15,
3.4,
15.75,
7,
3.5,
.1
);
/* computer window */
windowObj(
-20.75,
3.4,
-4,
.1,
3.5,
6
);
/* =========================================================
CEILING LIGHTS
========================================================= */
lamp(-14,5.6,8,25);
lamp(-14,5.6,-8,25);
lamp(2,5.6,1,28);
lamp(14,5.6,4,30);
lamp(14,5.6,-11,25);
lamp(12,5.6,13,25);
/* =========================================================
COMPUTER DESK
========================================================= */
const desk=new THREE.Group();
scene.add(desk);
desk.position.set(
-14,
0,
-3
);
/* tabletop */
box(
0,
2.35,
0,
6.5,.3,2.2,
wood,
desk
);
/* four legs */
for(const x of [-2.8,2.8]){
for(const z of [-.8,.8]){
box(
x,
1.15,
z,
.25,2.3,.25,
metal,
desk
);
}
}
/* drawers */
box(
-2.25,
1.25,
0,
1.3,1.7,1.7,
wood,
desk
);
/* =========================================================
COMPUTER
========================================================= */
const computer=new THREE.Group();
desk.add(computer);
computer.position.set(
1.9,
1.35,
0
);
/* case */
box(
0,
1,
0,
1.7,
2.5,
1.2,
black,
computer
);
/* glass side */
box(
.86,
1,
0,
.03,
2.2,
1,
glass,
computer
);
/* motherboard */
box(
.55,
1.15,
.1,
.05,
1.9,
.75,
green,
computer
);
/* CPU */
box(
.55,
1.5,
.25,
.35,.08,.35,
metal,
computer
);
/* RAM */
for(let x of [.4,.55]){
box(
x,
1.55,
-.05,
.06,.65,.35,
M(0x263c65,.25,.5),
computer
);
}
/* GPU */
box(
.3,
.7,
-.2,
1.25,.3,.65,
dark,
computer
);
/* GPU fans */
for(let x of [-.05,.35]){
const f=new THREE.Mesh(
new THREE.TorusGeometry(
.18,.045,12,24
),
metal
);
f.rotation.x=Math.PI/2;
f.position.set(
x,
.7,
-.55
);
computer.add(f);
}
/* front fans */
for(let y of [.55,1.15,1.75]){
const ring=new THREE.Mesh(
new THREE.TorusGeometry(
.25,.045,12,32
),
metal
);
ring.position.set(
0,
y,
-.63
);
computer.add(ring);
}
/* =========================================================
MONITOR
========================================================= */
const monitor=new THREE.Group();
desk.add(monitor);
monitor.position.set(
-.45,
3.15,
0
);
box(
0,
0,
0,
4.2,2.45,.16,
black,
monitor
);
const screenMaterial=new THREE.MeshStandardMaterial({
color:0x0d1822,
emissive:0x15344b,
emissiveIntensity:1,
roughness:.12
});
box(
0,
0,
-.1,
3.9,2.15,.03,
screenMaterial,
monitor
);
/* stand */
box(
0,
-1.5,
0,
.25,1,.25,
metal,
monitor
);
box(
0,
-1.95,
0,
1.5,.12,.8,
metal,
monitor
);
/* =========================================================
KEYBOARD
========================================================= */
const keyboard=new THREE.Group();
desk.add(keyboard);
keyboard.position.set(
-.4,
2.58,
.9
);
box(
0,
0,
0,
3.4,.12,1.1,
black,
keyboard
);
for(let row=0;row<4;row++){
for(let col=0;col<12;col++){
box(
-1.35+col*.23,
.09,
-.32+row*.19,
.17,.06,.13,
white,
keyboard
);
}
}
/* =========================================================
MOUSE
========================================================= */
sphere(
2,
2.72,
.95,
.28,
black,
desk
);
/* =========================================================
CABLES
========================================================= */
function tubeCable(points){
const curve=new THREE.CatmullRomCurve3(
points
);
const geometry=new THREE.TubeGeometry(
curve,
40,
.035,
8,
false
);
const mesh=new THREE.Mesh(
geometry,
black
);
mesh.castShadow=true;
scene.add(mesh);
}
/* keyboard cable */
tubeCable([
new THREE.Vector3(
-14.5,2.6,-2.1
),
new THREE.Vector3(
-15,2.4,-1.4
),
new THREE.Vector3(
-15.4,2.2,-.8
),
new THREE.Vector3(
-16,1.8,-.5
)
]);
/* mouse cable */
tubeCable([
new THREE.Vector3(
-11.8,2.65,-2.1
),
new THREE.Vector3(
-11.2,2.4,-1.7
),
new THREE.Vector3(
-10.9,2.1,-1
)
]);
/* =========================================================
LIVING ROOM SOFA
========================================================= */
function sofa(x,z){
const g=new THREE.Group();
scene.add(g);
g.position.set(
x,0,z
);
box(
0,1,
0,
6,.8,2.2,
M(0x4b4845,.95),
g
);
box(
0,2,
-.8,
6,1.8,.5,
M(0x403d3a,.95),
g
);
box(
-2.7,1.5,
0,
.5,1.7,2.2,
M(0x403d3a,.95),
g
);
box(
2.7,1.5,
0,
.5,1.7,2.2,
M(0x403d3a,.95),
g
);
}
sofa(
13,
3
);
/* coffee table */
box(
13,
.7,
7,
4,.15,2,
wood
);
for(const x of [11.5,14.5]){
for(const z of [6.4,7.6]){
box(
x,
.35,
z,
.15,.7,.15,
metal
);
}
}
/* =========================================================
TV
========================================================= */
box(
13,
2.8,
15.4,
7,
4,
.3,
black
);
box(
13,
2.8,
15.2,
6.5,
3.5,
.04,
screenMaterial
);
box(
13,
.7,
15.4,
1.5,
1,
1,
dark
);
/* =========================================================
KITCHEN
========================================================= */
const kitchenX=13;
const kitchenZ=-2;
/* cabinets */
for(let i=0;i<5;i++){
box(
9+i*2,
1,
-3.5,
1.7,2,1,
wood
);
}
/* countertop */
box(
13,
2.05,
-3.5,
10,.25,1.1,
M(0x6b6d69,.45,.15)
);
/* upper cabinets */
for(let i=0;i<5;i++){
box(
9+i*2,
4.2,
-3.7,
1.7,1.6,.7,
wood
);
}
/* fridge */
box(
19,
2.5,
-7,
2,
5,
2,
white
);
/* oven */
box(
13,
1.3,
-3.95,
1.5,
1.1,
.08,
black
);
/* sink */
box(
17,
2.18,
-3.5,
1.3,.08,.7,
white
);
/* =========================================================
BEDROOM
========================================================= */
box(
13,
.7,
12,
6,
1.2,
4.5,
wood
);
box(
13,
1.4,
11.5,
5.7,
.4,
4,
white
);
/* headboard */
box(
13,
2.6,
14.1,
6,
2.8,
.25,
wood
);
/* pillows */
box(
11.3,
1.8,
10.5,
1.5,.35,1,
white
);
box(
14.7,
1.8,
10.5,
1.5,.35,1,
white
);
/* wardrobe */
box(
18,
2.5,
12,
2.5,
5,
2,
wood
);
/* =========================================================
BATHROOM
========================================================= */
/* toilet body */
box(
17,
.55,
-12.5,
1.4,
.8,
1.6,
white
);
box(
17,
1.4,
-13,
1.2,
1.1,
.35,
white
);
/* sink cabinet */
box(
10,
.8,
-12.5,
2,
1.5,
1,
wood
);
box(
10,
1.6,
-12.5,
2.1,
.12,
1.05,
white
);
/* mirror */
box(
10,
3.3,
-13.05,
2.2,
2.2,
.06,
glass
);
/* bathtub */
box(
15,
.7,
-8.7,
5,
1.1,
1.7,
white
);
box(
15,
1.3,
-8.7,
4.5,
.1,
1.3,
glass
);
/* shower pipe */
cyl(
18,
3.3,
-8.7,
.08,
4,
metal
);
cyl(
18,
5.15,
-8.7,
.35,
.15,
metal
);
/* =========================================================
DECOR
========================================================= */
function painting(
x,y,z,
sx,sy
){
box(
x,y,z,
sx,sy,.12,
dark
);
box(
x,y,z-.08,
sx-.2,
sy-.2,
.03,
M(0x506c79,.8)
);
}
painting(
20.7,
3,
10,
.12,
3
);
/* =========================================================
OUTSIDE TREES
========================================================= */
function tree(x,z){
cyl(
x,
2,
z,
.3,
4,
M(0x543a25,.95)
);
sphere(
x,
4.6,
z,
1.6,
M(0x36563b,.95)
);
sphere(
x-.9,
4,
z+.2,
1.1,
M(0x3e6645,.95)
);
sphere(
x+.8,
4.1,
z-.2,
1.15,
M(0x34583c,.95)
);
}
tree(-30,-5);
tree(-30,10);
tree(30,-5);
tree(30,10);
tree(-25,25);
tree(25,25);
/* =========================================================
PLAYER
========================================================= */
const player=new THREE.Group();
scene.add(player);
player.position.set(
0,
0,
10
);
/* body */
const character=new THREE.Group();
player.add(character);
/* torso */
box(
0,
1.15,
0,
.85,
1.35,
.5,
M(0x33404c,.75),
character
);
/* head */
sphere(
0,
2.35,
0,
.42,
M(0xc79272,.85),
character
);
/* hair */
sphere(
0,
2.6,
0,
.43,
black,
character
);
/* arms */
const armL=new THREE.Group();
const armR=new THREE.Group();
character.add(armL);
character.add(armR);
armL.position.set(
-.58,1.6,0
);
armR.position.set(
.58,1.6,0
);
box(
0,-.45,0,
.28,.9,.28,
M(0x33404c,.8),
armL
);
box(
0,-.45,0,
.28,.9,.28,
M(0x33404c,.8),
armR
);
s⚠️Content was pasted as plain text and auto-formatted as a code block. Use the Code Block button in the editor for proper formatting.