awacke1 commited on
Commit
033fbe6
Β·
verified Β·
1 Parent(s): ccc8baf

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +168 -476
index.html CHANGED
@@ -1,495 +1,187 @@
1
  <!DOCTYPE html>
2
- <html>
3
  <head>
4
- <title>Three.js Infinite World</title>
5
- <style>
6
- body { margin: 0; overflow: hidden; }
7
- canvas { display: block; }
8
- </style>
9
- <!-- New: Polling function for game state -->
10
- <script>
11
- // Poll the shared game state every 5 seconds (for demonstration)
12
- function pollGameState() {
13
- console.log("Polling updated game state:", window.GAME_STATE);
14
- // Here you could update the scene based on the new state.
15
- }
16
- setInterval(pollGameState, 5000);
17
- </script>
18
- </head>
19
- <body>
20
- <script type="importmap">
21
- {
22
- "imports": {
23
- "three": "https://unpkg.com/[email protected]/build/three.module.js",
24
- "three/addons/": "https://unpkg.com/[email protected]/examples/jsm/"
25
- }
26
- }
27
- </script>
28
 
29
- <script type="module">
30
- import * as THREE from 'three';
31
- let scene, camera, renderer, playerMesh;
32
- let raycaster, mouse;
33
- const keysPressed = {};
34
- const playerSpeed = 0.15;
35
- let newlyPlacedObjects = []; // Track objects added THIS session for saving
36
- const placeholderPlots = new Set();
37
- const groundMeshes = {}; // Store ground mesh references
38
- // --- Session Storage Key ---
39
- const SESSION_STORAGE_KEY = 'unsavedInfiniteWorldState';
40
- // --- Injected State from Streamlit ---
41
- const allInitialObjects = window.ALL_INITIAL_OBJECTS || [];
42
- const plotsMetadata = window.PLOTS_METADATA || [];
43
- const selectedObjectType = window.SELECTED_OBJECT_TYPE || "None";
44
- const plotWidth = window.PLOT_WIDTH || 50.0;
45
- const plotDepth = window.PLOT_DEPTH || 50.0;
46
- const groundMaterial = new THREE.MeshStandardMaterial({
47
- color: 0x55aa55, roughness: 0.9, metalness: 0.1, side: THREE.DoubleSide
48
- });
49
- const placeholderGroundMaterial = new THREE.MeshStandardMaterial({
50
- color: 0x448844, roughness: 0.95, metalness: 0.1, side: THREE.DoubleSide
51
- });
52
 
53
- // ─── Helper to tag every object/group with type & unique ID ──────────────
54
- function createObjectBase(type) {
55
- return { userData: { type: type, obj_id: THREE.MathUtils.generateUUID() } };
56
- }
 
 
 
 
 
57
 
58
- // ─── Primitive creators ─────────────────────────────────────────────────
59
- function createSimpleHouse() {
60
- const base = createObjectBase("Simple House");
61
- const group = new THREE.Group();
62
- Object.assign(group, base);
63
- const mat1 = new THREE.MeshStandardMaterial({ color: 0xffccaa, roughness: 0.8 });
64
- const mat2 = new THREE.MeshStandardMaterial({ color: 0xaa5533, roughness: 0.7 });
65
- const m1 = new THREE.Mesh(new THREE.BoxGeometry(2, 1.5, 2.5), mat1);
66
- m1.position.y = 1.5/2;
67
- m1.castShadow = m1.receiveShadow = true;
68
- group.add(m1);
69
- const m2 = new THREE.Mesh(new THREE.ConeGeometry(1.8, 1, 4), mat2);
70
- m2.position.y = 1.5 + 0.5;
71
- m2.rotation.y = Math.PI/4;
72
- m2.castShadow = m2.receiveShadow = true;
73
- group.add(m2);
74
- return group;
75
- }
76
 
77
- function createTree() {
78
- const base = createObjectBase("Tree");
79
- const group = new THREE.Group();
80
- Object.assign(group, base);
81
- const matTrunk = new THREE.MeshStandardMaterial({ color: 0x8B4513, roughness: 0.9 });
82
- const matFoliage = new THREE.MeshStandardMaterial({ color: 0x228B22, roughness: 0.8 });
83
- const trunk = new THREE.Mesh(new THREE.CylinderGeometry(0.3, 0.4, 2, 8), matTrunk);
84
- trunk.position.y = 1;
85
- trunk.castShadow = trunk.receiveShadow = true;
86
- group.add(trunk);
87
- const foliage = new THREE.Mesh(new THREE.IcosahedronGeometry(1.2, 0), matFoliage);
88
- foliage.position.y = 2.8;
89
- foliage.castShadow = foliage.receiveShadow = true;
90
- group.add(foliage);
91
- return group;
92
- }
 
 
 
93
 
94
- function createRock() {
95
- const base = createObjectBase("Rock");
96
- const mat = new THREE.MeshStandardMaterial({ color: 0xaaaaaa, roughness: 0.8, metalness: 0.1 });
97
- const rock = new THREE.Mesh(new THREE.IcosahedronGeometry(0.7, 0), mat);
98
- Object.assign(rock, base);
99
- rock.position.y = 0.35;
100
- rock.rotation.set(Math.random()*Math.PI, Math.random()*Math.PI, 0);
101
- rock.castShadow = rock.receiveShadow = true;
102
- return rock;
103
- }
104
 
105
- function createFencePost() {
106
- const base = createObjectBase("Fence Post");
107
- const mat = new THREE.MeshStandardMaterial({ color: 0xdeb887, roughness: 0.9 });
108
- const post = new THREE.Mesh(new THREE.BoxGeometry(0.2, 1.5, 0.2), mat);
109
- Object.assign(post, base);
110
- post.position.y = 0.75;
111
- post.castShadow = post.receiveShadow = true;
112
- return post;
113
- }
 
 
 
114
 
115
- // ─── 1. Cyberpunk City Builder Kit ────────────────────────────────────────
116
- function createCyberpunkWallPanel({
117
- width=2, height=3, depth=0.2,
118
- baseMat={ color:0x555555, metalness:0.8, roughness:0.4 },
119
- trimMat={ emissive:0x00ffff, emissiveIntensity:1.2 },
120
- position=new THREE.Vector3()
121
- } = {}) {
122
- const panelBase = new THREE.BoxGeometry(width, height, depth);
123
- const panel = new THREE.Mesh(panelBase, new THREE.MeshStandardMaterial(baseMat));
124
- panel.position.copy(position);
125
- return panel;
126
- }
127
- function createRooftopACUnit({
128
- width=1, height=0.5, depth=1,
129
- matProps={ color:0x777777, roughness:0.7, metalness:0.3 },
130
- position=new THREE.Vector3()
131
- } = {}) {
132
- const unit = new THREE.Mesh(
133
- new THREE.BoxGeometry(width, height, depth),
134
- new THREE.MeshStandardMaterial(matProps)
135
- );
136
- unit.position.copy(position);
137
- return unit;
138
- }
139
- function createHolographicWindowDisplay({
140
- width=1.5, height=1, position=new THREE.Vector3()
141
- } = {}) {
142
- const geom = new THREE.PlaneGeometry(width, height);
143
- const mat = new THREE.MeshBasicMaterial({
144
- color:0xffffff, transparent:true, opacity:0.6
145
- });
146
- const disp = new THREE.Mesh(geom, mat);
147
- disp.position.copy(position);
148
- return disp;
149
- }
150
- function createGreebleSet({
151
- count=10, scale=0.2, position=new THREE.Vector3()
152
- } = {}) {
153
- const grp = new THREE.Group();
154
- for(let i=0; i<count; i++){
155
- const dx = (Math.random()-0.5)*2;
156
- const dy = (Math.random()-0.5)*2;
157
- const dz = (Math.random()-0.5)*0.2;
158
- const g = new THREE.Mesh(
159
- new THREE.BoxGeometry(scale, scale, scale),
160
- new THREE.MeshStandardMaterial({ color:0x444444, roughness:0.6, metalness:0.4 })
161
- );
162
- g.position.copy(position).add(new THREE.Vector3(dx,dy,dz));
163
- grp.add(g);
164
- }
165
- return grp;
166
- }
167
- function createCyberpunkKit() {
168
- const base = createObjectBase("Cyberpunk City Builder Kit");
169
- const kit = new THREE.Group();
170
- Object.assign(kit, base);
171
- kit.add(createCyberpunkWallPanel({ position:new THREE.Vector3(0,1,0) }));
172
- kit.add(createRooftopACUnit({ position:new THREE.Vector3(3,0.5,0) }));
173
- kit.add(createHolographicWindowDisplay({ position:new THREE.Vector3(6,1,0) }));
174
- kit.add(createGreebleSet({ position:new THREE.Vector3(9,0,0) }));
175
- return kit;
176
- }
177
 
178
- // ─── 2. POLYGON – Fantasy Kingdom Pack ───────────────────────────────────
179
- function createKingFigure({ position=new THREE.Vector3() } = {}) {
180
- const base = createObjectBase("POLYGON - Fantasy Kingdom Pack");
181
- const mesh = new THREE.Mesh(
182
- new THREE.CylinderGeometry(0.3,0.5,1.8,6),
183
- new THREE.MeshStandardMaterial({ color:0xffd700, metalness:0.9, roughness:0.2 })
184
- );
185
- Object.assign(mesh, base);
186
- mesh.position.copy(position);
187
- return mesh;
188
- }
189
- function createSoldierFigure({ position=new THREE.Vector3() } = {}) {
190
- const base = createObjectBase("POLYGON - Fantasy Kingdom Pack");
191
- const mesh = new THREE.Mesh(
192
- new THREE.BoxGeometry(0.5,1.6,0.4),
193
- new THREE.MeshStandardMaterial({ color:0x888888, metalness:0.6, roughness:0.4 })
194
- );
195
- Object.assign(mesh, base);
196
- mesh.position.copy(position);
197
- return mesh;
198
- }
199
- function createMageFigure({ position=new THREE.Vector3() } = {}) {
200
- const base = createObjectBase("POLYGON - Fantasy Kingdom Pack");
201
- const mesh = new THREE.Mesh(
202
- new THREE.ConeGeometry(0.4,1.5,6),
203
- new THREE.MeshStandardMaterial({ color:0x9933ff, roughness:0.5 })
204
- );
205
- Object.assign(mesh, base);
206
- mesh.position.copy(position);
207
- return mesh;
208
- }
209
- function createFantasyKingdomPack() {
210
- const grp = new THREE.Group();
211
- Object.assign(grp, createObjectBase("POLYGON - Fantasy Kingdom Pack"));
212
- grp.add(createKingFigure({ position:new THREE.Vector3(0,0,0) }));
213
- grp.add(createSoldierFigure({ position:new THREE.Vector3(2,0,0) }));
214
- grp.add(createMageFigure({ position:new THREE.Vector3(4,0,0) }));
215
- return grp;
216
- }
217
 
218
- // ─── 3. HEROIC FANTASY CREATURES FULL PACK VOLΒ 1 ─────────────────────────
219
- function createDemonicCreatureBase({ position=new THREE.Vector3() }={}) {
220
- const base = createObjectBase("HEROIC FANTASY CREATURES FULL PACK VOLΒ 1");
221
- const mesh = new THREE.Mesh(
222
- new THREE.SphereGeometry(0.8,8,6),
223
- new THREE.MeshStandardMaterial({ color:0x550000, roughness:0.7 })
224
- );
225
- Object.assign(mesh, base);
226
- mesh.position.copy(position);
227
- return mesh;
228
- }
229
- function createFantasyAnimalBase({ position=new THREE.Vector3() }={}) {
230
- const base = createObjectBase("HEROIC FANTASY CREATURES FULL PACK VOLΒ 1");
231
- const mesh = new THREE.Mesh(
232
- new THREE.BoxGeometry(1.2,0.6,2),
233
- new THREE.MeshStandardMaterial({ color:0x665533, roughness:0.8 })
234
- );
235
- Object.assign(mesh, base);
236
- mesh.position.copy(position);
237
- return mesh;
238
- }
239
- function createFantasyLizardBase({ position=new THREE.Vector3() }={}) {
240
- const base = createObjectBase("HEROIC FANTASY CREATURES FULL PACK VOLΒ 1");
241
- const mesh = new THREE.Mesh(
242
- new THREE.ConeGeometry(0.3,1,6),
243
- new THREE.MeshStandardMaterial({ color:0x339933, roughness:0.6 })
244
- );
245
- Object.assign(mesh, base);
246
- mesh.position.copy(position);
247
- return mesh;
248
- }
249
- function createLivingDeadBase({ position=new THREE.Vector3() }={}) {
250
- const base = createObjectBase("HEROIC FANTASY CREATURES FULL PACK VOLΒ 1");
251
- const mesh = new THREE.Mesh(
252
- new THREE.BoxGeometry(0.8,1.8,0.5),
253
- new THREE.MeshStandardMaterial({ color:0x777777, roughness:0.9 })
254
- );
255
- Object.assign(mesh, base);
256
- mesh.position.copy(position);
257
- return mesh;
258
- }
259
- function createFantasyVillainBase({ position=new THREE.Vector3() }={}) {
260
- const base = createObjectBase("HEROIC FANTASY CREATURES FULL PACK VOLΒ 1");
261
- const mesh = new THREE.Mesh(
262
- new THREE.OctahedronGeometry(0.9,0),
263
- new THREE.MeshStandardMaterial({ color:0x220022, roughness:0.7 })
264
- );
265
- Object.assign(mesh, base);
266
- mesh.position.copy(position);
267
- return mesh;
268
- }
269
- function createMythologicalCreatureBase({ position=new THREE.Vector3() }={}) {
270
- const base = createObjectBase("HEROIC FANTASY CREATURES FULL PACK VOLΒ 1");
271
- const mesh = new THREE.Mesh(
272
- new THREE.TorusKnotGeometry(0.5,0.2,100,16),
273
- new THREE.MeshStandardMaterial({ color:0xdddd00, roughness:0.5 })
274
- );
275
- Object.assign(mesh, base);
276
- mesh.position.copy(position);
277
- return mesh;
278
- }
279
- function createHeroicFantasyCreaturesPack() {
280
- const grp = new THREE.Group();
281
- Object.assign(grp, createObjectBase("HEROIC FANTASY CREATURES FULL PACK VOLΒ 1"));
282
- grp.add(createDemonicCreatureBase({ position:new THREE.Vector3(0,0,0) }));
283
- grp.add(createFantasyAnimalBase({ position:new THREE.Vector3(3,0,0) }));
284
- grp.add(createFantasyLizardBase({ position:new THREE.Vector3(6,0,0) }));
285
- grp.add(createLivingDeadBase({ position:new THREE.Vector3(9,0,0) }));
286
- grp.add(createFantasyVillainBase({ position:new THREE.Vector3(12,0,0) }));
287
- grp.add(createMythologicalCreatureBase({ position:new THREE.Vector3(15,0,0) }));
288
- return grp;
289
- }
290
 
291
- // ─── 4. POLYGON – Apocalypse Pack (Low Poly) ─────────────────────────────
292
- function createZombieFigure({ position=new THREE.Vector3() }={}) {
293
- const base = createObjectBase("POLYGON - Apocalypse Pack");
294
- const mesh = new THREE.Mesh(
295
- new THREE.BoxGeometry(0.5,1.7,0.4),
296
- new THREE.MeshStandardMaterial({ color:0x445544, roughness:0.9 })
297
- );
298
- Object.assign(mesh, base);
299
- mesh.position.copy(position);
300
- return mesh;
301
- }
302
- function createSurvivorFigure({ position=new THREE.Vector3() }={}) {
303
- const base = createObjectBase("POLYGON - Apocalypse Pack");
304
- const mesh = new THREE.Mesh(
305
- new THREE.BoxGeometry(0.5,1.7,0.4),
306
- new THREE.MeshStandardMaterial({ color:0x885522, roughness:0.7 })
307
- );
308
- Object.assign(mesh, base);
309
- mesh.position.copy(position);
310
- return mesh;
311
- }
312
- function createBackpack({ position=new THREE.Vector3() }={}) {
313
- const base = createObjectBase("POLYGON - Apocalypse Pack");
314
- const mesh = new THREE.Mesh(
315
- new THREE.BoxGeometry(0.6,0.8,0.3),
316
- new THREE.MeshStandardMaterial({ color:0x333333, roughness:0.8 })
317
- );
318
- Object.assign(mesh, base);
319
- mesh.position.copy(position);
320
- return mesh;
321
- }
322
- function createMakeshiftArmor({ position=new THREE.Vector3() }={}) {
323
- const base = createObjectBase("POLYGON - Apocalypse Pack");
324
- const mesh = new THREE.Mesh(
325
- new THREE.BoxGeometry(1,1.2,0.2),
326
- new THREE.MeshStandardMaterial({ color:0x555555, roughness:0.9 })
327
- );
328
- Object.assign(mesh, base);
329
- mesh.position.copy(position);
330
- return mesh;
331
- }
332
- function createBuggyFrame({ position=new THREE.Vector3() }={}) {
333
- const base = createObjectBase("POLYGON - Apocalypse Pack");
334
- const mesh = new THREE.Mesh(
335
- new THREE.BoxGeometry(2,0.5,1.2),
336
- new THREE.MeshStandardMaterial({ color:0x666666, roughness:0.7 })
337
- );
338
- Object.assign(mesh, base);
339
- mesh.position.copy(position);
340
- return mesh;
341
- }
342
- function createApocalypsePack() {
343
- const grp = new THREE.Group();
344
- Object.assign(grp, createObjectBase("POLYGON - Apocalypse Pack"));
345
- grp.add(createZombieFigure({ position:new THREE.Vector3(0,0,0) }));
346
- grp.add(createSurvivorFigure({ position:new THREE.Vector3(3,0,0) }));
347
- grp.add(createBackpack({ position:new THREE.Vector3(6,0,0) }));
348
- grp.add(createMakeshiftArmor({ position:new THREE.Vector3(9,0,0) }));
349
- grp.add(createBuggyFrame({ position:new THREE.Vector3(12,0,0) }));
350
- return grp;
351
- }
352
 
353
- // ─── Existing loader that places from Python data ────────────────────────
354
- function createAndPlaceObject(objData, isNewObject) {
355
- let loadedObject = null;
356
- switch (objData.type) {
357
- case "Simple House": loadedObject = createSimpleHouse(); break;
358
- case "Tree": loadedObject = createTree(); break;
359
- case "Rock": loadedObject = createRock(); break;
360
- case "Fence Post": loadedObject = createFencePost(); break;
361
- case "Cyberpunk City Builder Kit":
362
- loadedObject = createCyberpunkKit(); break;
363
- case "POLYGON - Fantasy Kingdom Pack":
364
- loadedObject = createFantasyKingdomPack(); break;
365
- case "HEROIC FANTASY CREATURES FULL PACK VOLΒ 1":
366
- loadedObject = createHeroicFantasyCreaturesPack(); break;
367
- case "POLYGON - Apocalypse Pack":
368
- loadedObject = createApocalypsePack(); break;
369
- default: console.warn("Unknown object type in data:", objData.type); break;
370
- }
371
- if (loadedObject) {
372
- // position & rotation from CSV or JSON
373
- if (objData.position && objData.position.x !== undefined) {
374
- loadedObject.position.set(objData.position.x, objData.position.y, objData.position.z);
375
- } else if (objData.pos_x !== undefined) {
376
- loadedObject.position.set(objData.pos_x, objData.pos_y, objData.pos_z);
377
- }
378
- if (objData.rotation) {
379
- loadedObject.rotation.set(
380
- objData.rotation._x, objData.rotation._y, objData.rotation._z
381
- );
382
- } else if (objData.rot_x !== undefined) {
383
- loadedObject.rotation.set(
384
- objData.rot_x, objData.rot_y, objData.rot_z
385
- );
386
- }
387
- scene.add(loadedObject);
388
- if (isNewObject) newlyPlacedObjects.push(loadedObject);
389
- return loadedObject;
390
- }
391
- return null;
392
- }
393
 
394
- // ─── Setup, Animate etc. (unchanged) ────────────────────────────────────
395
- function init() {
396
- scene = new THREE.Scene();
397
- scene.background = new THREE.Color(0xabcdef);
398
- const aspect = window.innerWidth / window.innerHeight;
399
- camera = new THREE.PerspectiveCamera(60, aspect, 0.1, 4000);
400
- camera.position.set(0,15,20);
401
- camera.lookAt(0,0,0);
402
- scene.add(camera);
403
- setupLighting();
404
- setupInitialGround();
405
- setupPlayer();
406
- raycaster = new THREE.Raycaster();
407
- mouse = new THREE.Vector2();
408
- renderer = new THREE.WebGLRenderer({ antialias: true });
409
- renderer.setSize(window.innerWidth, window.innerHeight);
410
- renderer.shadowMap.enabled = true;
411
- renderer.shadowMap.type = THREE.PCFSoftShadowMap;
412
- document.body.appendChild(renderer.domElement);
413
- loadInitialObjects();
414
- restoreUnsavedState();
415
- document.addEventListener('mousemove', onMouseMove, false);
416
- document.addEventListener('click', onDocumentClick, false);
417
- window.addEventListener('resize', onWindowResize, false);
418
- document.addEventListener('keydown', onKeyDown);
419
- document.addEventListener('keyup', onKeyUp);
420
- window.teleportPlayer = teleportPlayer;
421
- window.getSaveDataAndPosition = getSaveDataAndPosition;
422
- window.resetNewlyPlacedObjects = resetNewlyPlacedObjects;
423
- console.log("Three.js Initialized. World ready.");
424
- animate();
425
- }
426
 
427
- // ─── Click to place logic ───────────────────────────────────────────────
428
- function onDocumentClick(event) {
429
- if (selectedObjectType === "None") return;
430
- const grounds = Object.values(groundMeshes);
431
- if (!grounds.length) return;
432
- raycaster.setFromCamera(mouse, camera);
433
- const hits = raycaster.intersectObjects(grounds);
434
- if (hits.length) {
435
- const pt = hits[0].point;
436
- let newObj = null;
437
- switch (selectedObjectType) {
438
- case "Simple House": newObj = createSimpleHouse(); break;
439
- case "Tree": newObj = createTree(); break;
440
- case "Rock": newObj = createRock(); break;
441
- case "Fence Post": newObj = createFencePost(); break;
442
- case "Cyberpunk City Builder Kit":
443
- newObj = createCyberpunkKit(); break;
444
- case "POLYGON - Fantasy Kingdom Pack":
445
- newObj = createFantasyKingdomPack(); break;
446
- case "HEROIC FANTASY CREATURES FULL PACK VOLΒ 1":
447
- newObj = createHeroicFantasyCreaturesPack(); break;
448
- case "POLYGON - Apocalypse Pack":
449
- newObj = createApocalypsePack(); break;
450
- default: return;
451
- }
452
- if (newObj) {
453
- newObj.position.copy(pt);
454
- newObj.position.y += 0.01;
455
- scene.add(newObj);
456
- newlyPlacedObjects.push(newObj);
457
- saveUnsavedState();
458
- console.log(`Placed new ${selectedObjectType}. Unsaved total: ${newlyPlacedObjects.length}`);
459
- }
460
- }
461
- }
462
 
463
- // ─── Rest of your functions: save/restore state, movement, animate, etc. ──
464
- function saveUnsavedState() { /* unchanged */ }
465
- function restoreUnsavedState() { /* unchanged */ }
466
- function clearUnsavedState() { /* unchanged */ }
467
- function teleportPlayer(x,z) { /* unchanged */ }
468
- function getSaveDataAndPosition() { /* unchanged */ }
469
- function resetNewlyPlacedObjects() { /* unchanged */ }
470
- function updatePlayerMovement() { /* unchanged */ }
471
- function checkAndExpandGround() { /* unchanged */ }
472
- function updateCamera() { /* unchanged */ }
473
- function onMouseMove(event) {
474
- mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
475
- mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
476
- }
477
- function onKeyDown(e) { keysPressed[e.code] = true; }
478
- function onKeyUp(e) { keysPressed[e.code] = false; }
479
- function onWindowResize() {
480
- camera.aspect = window.innerWidth / window.innerHeight;
481
- camera.updateProjectionMatrix();
482
- renderer.setSize(window.innerWidth, window.innerHeight);
483
- }
484
- function animate() {
485
- requestAnimationFrame(animate);
486
- updatePlayerMovement();
487
- updateCamera();
488
- renderer.render(scene, camera);
489
- }
490
 
491
- // ─── Kick it off ────────────────────────────────────────────────────────
492
- init();
493
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494
  </body>
495
  </html>
 
1
  <!DOCTYPE html>
2
+ <html lang="en">
3
  <head>
4
+ <meta charset="UTF-8" />
5
+ <title>Infinite World</title>
6
+ <style>
7
+ body { margin:0; overflow:hidden; }
8
+ canvas { display:block; }
9
+ </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ <script type="module">
12
+ import * as THREE from 'three';
13
+ // … your existing three.js init, camera, lights, renderer, controls …
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ // ─── Primitive helpers ──────────────────────────────────────────────────
16
+ function createBox({width, height, depth, materialProps, position}) {
17
+ const geom = new THREE.BoxGeometry(width, height, depth);
18
+ const mat = new THREE.MeshStandardMaterial(materialProps);
19
+ const mesh = new THREE.Mesh(geom, mat);
20
+ mesh.position.copy(position);
21
+ return mesh;
22
+ }
23
+ // … any other helpers like createPlane(), createSplineTube(), createParticles() …
24
 
25
+ // ─── Existing simple creators ───────────────────────────────────────────
26
+ // function createSimpleHouse(...) { … }
27
+ // function createTree(...) { … }
28
+ // function createRock(...) { … }
29
+ // function createFencePost(...) { … }
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ // ─── 1. Cyberpunk City Builder Kit ────────────────────────────────────────
32
+ function createCyberpunkWallPanel({
33
+ width=2, height=3, depth=0.2,
34
+ baseMaterial={ color:0x555555, metalness:0.8, roughness:0.4 },
35
+ trimMaterial={ emissive:0x00ffff, emissiveIntensity:1.2 },
36
+ windowCutouts=true, doorCutouts=false,
37
+ position=new THREE.Vector3()
38
+ }) {
39
+ const panel = createBox({ width, height, depth, materialProps: baseMaterial, position });
40
+ // trim
41
+ const trim = createBox({
42
+ width: width * 0.1, height: height, depth: depth + 0.01,
43
+ materialProps: trimMaterial,
44
+ position: position.clone().add(new THREE.Vector3(width/2 + 0.05, 0, 0))
45
+ });
46
+ panel.add(trim);
47
+ // TODO: boolean cutouts for windows/doors
48
+ return panel;
49
+ }
50
 
51
+ function createRooftopACUnit({
52
+ width=1, height=0.5, depth=1,
53
+ materialProps={ color:0x777777, roughness:0.7, metalness:0.3 },
54
+ position=new THREE.Vector3()
55
+ }) {
56
+ const unit = createBox({ width, height, depth, materialProps, position });
57
+ // grill detail, pipes, etc.
58
+ return unit;
59
+ }
 
60
 
61
+ function createHolographicWindowDisplay({
62
+ width=1.5, height=1, position=new THREE.Vector3()
63
+ }) {
64
+ const planeMat = new THREE.MeshBasicMaterial({
65
+ color: 0xffffff, transparent:true, opacity:0.6
66
+ });
67
+ const geom = new THREE.PlaneGeometry(width, height);
68
+ const display = new THREE.Mesh(geom, planeMat);
69
+ display.position.copy(position);
70
+ // animate emissive shader parameter here…
71
+ return display;
72
+ }
73
 
74
+ function createGreebleSet({
75
+ count=10, scale=0.2, position=new THREE.Vector3()
76
+ }) {
77
+ const group = new THREE.Group();
78
+ for(let i=0; i<count; i++){
79
+ const x = (Math.random()-0.5)*2;
80
+ const y = (Math.random()-0.5)*2;
81
+ const z = (Math.random()-0.5)*0.2;
82
+ const pebble = createBox({
83
+ width: scale, height: scale, depth: scale,
84
+ materialProps:{ color:0x444444, roughness:0.6, metalness:0.4 },
85
+ position: position.clone().add(new THREE.Vector3(x,y,z))
86
+ });
87
+ group.add(pebble);
88
+ }
89
+ return group;
90
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
+ function createCyberpunkKit(position=new THREE.Vector3()) {
93
+ const kit = new THREE.Group();
94
+ kit.add(createCyberpunkWallPanel({ position: position.clone() }));
95
+ kit.add(createRooftopACUnit({ position: position.clone().add(new THREE.Vector3(3,0,0)) }));
96
+ kit.add(createHolographicWindowDisplay({ position: position.clone().add(new THREE.Vector3(6,1,0)) }));
97
+ kit.add(createGreebleSet({ position: position.clone().add(new THREE.Vector3(9,0,0)) }));
98
+ scene.add(kit);
99
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
+ // ─── 2. POLYGON – Fantasy Kingdom Pack ───────────────────────────────────
102
+ function createKingFigure({
103
+ scale=1, materialProps={ color:0xffd700, metalness:0.9, roughness:0.2 },
104
+ position=new THREE.Vector3()
105
+ }) {
106
+ // placeholder low‐poly silhouette
107
+ const geom = new THREE.CylinderGeometry(0.3*scale, 0.5*scale, 1.8*scale, 6);
108
+ const mesh = new THREE.Mesh(geom, new THREE.MeshStandardMaterial(materialProps));
109
+ mesh.position.copy(position);
110
+ return mesh;
111
+ }
112
+ function createSoldierFigure({ position=new THREE.Vector3() }) { /*…*/ }
113
+ function createMageFigure({ position=new THREE.Vector3() }) { /*…*/ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
+ function createFantasyKingdomPack(position=new THREE.Vector3()) {
116
+ const pack = new THREE.Group();
117
+ pack.add(createKingFigure({ position }));
118
+ pack.add(createSoldierFigure({ position: position.clone().add(new THREE.Vector3(2,0,0)) }));
119
+ pack.add(createMageFigure({ position: position.clone().add(new THREE.Vector3(4,0,0)) }));
120
+ scene.add(pack);
121
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
+ // ─── 3. HEROIC FANTASY CREATURES FULL PACK VOLΒ 1 ─────────────────────────
124
+ function createDemonicCreatureBase({ position=new THREE.Vector3() }) { /*…*/ }
125
+ function createFantasyAnimalBase({ position=new THREE.Vector3() }) { /*…*/ }
126
+ function createFantasyLizardBase({ position=new THREE.Vector3() }) { /*…*/ }
127
+ function createLivingDeadBase({ position=new THREE.Vector3() }) { /*…*/ }
128
+ function createFantasyVillainBase({ position=new THREE.Vector3() }) { /*…*/ }
129
+ function createMythologicalCreatureBase({ position=new THREE.Vector3() }) { /*…*/ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
+ function createHeroicFantasyCreaturesPack(position=new THREE.Vector3()) {
132
+ const grp = new THREE.Group();
133
+ grp.add(createDemonicCreatureBase({ position }));
134
+ grp.add(createFantasyAnimalBase({ position: position.clone().add(new THREE.Vector3(3,0,0)) }));
135
+ grp.add(createFantasyLizardBase({ position: position.clone().add(new THREE.Vector3(6,0,0)) }));
136
+ grp.add(createLivingDeadBase({ position: position.clone().add(new THREE.Vector3(9,0,0)) }));
137
+ grp.add(createFantasyVillainBase({ position: position.clone().add(new THREE.Vector3(12,0,0)) }));
138
+ grp.add(createMythologicalCreatureBase({ position: position.clone().add(new THREE.Vector3(15,0,0)) }));
139
+ scene.add(grp);
140
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
 
142
+ // ─── 4. POLYGON – Apocalypse Pack ─────────────────────────────────────────
143
+ function createZombieFigure({ position=new THREE.Vector3() }) { /*…*/ }
144
+ function createSurvivorFigure({ position=new THREE.Vector3() }) { /*…*/ }
145
+ function createBackpack({ position=new THREE.Vector3() }) { /*…*/ }
146
+ function createMakeshiftArmor({ position=new THREE.Vector3() }) { /*…*/ }
147
+ function createBuggyFrame({ position=new THREE.Vector3() }) { /*…*/ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
 
149
+ function createApocalypsePack(position=new THREE.Vector3()) {
150
+ const pack = new THREE.Group();
151
+ pack.add(createZombieFigure({ position }));
152
+ pack.add(createSurvivorFigure({ position: position.clone().add(new THREE.Vector3(3,0,0)) }));
153
+ pack.add(createBackpack({ position: position.clone().add(new THREE.Vector3(6,0,0)) }));
154
+ pack.add(createMakeshiftArmor({ position: position.clone().add(new THREE.Vector3(9,0,0)) }));
155
+ pack.add(createBuggyFrame({ position: position.clone().add(new THREE.Vector3(12,0,0)) }));
156
+ scene.add(pack);
157
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
+ // ─── Hook into your existing object‐placement switch ─────────────────────
160
+ window.placeObject = function(type, position) {
161
+ switch(type) {
162
+ case 'Cyberpunk City Builder Kit':
163
+ createCyberpunkKit(position);
164
+ break;
165
+ case 'POLYGON - Fantasy Kingdom Pack':
166
+ createFantasyKingdomPack(position);
167
+ break;
168
+ case 'HEROIC FANTASY CREATURES FULL PACKΒ VOLΒ 1':
169
+ createHeroicFantasyCreaturesPack(position);
170
+ break;
171
+ case 'POLYGON - Apocalypse Pack':
172
+ createApocalypsePack(position);
173
+ break;
174
+
175
+ // … your existing cases for Simple House, Tree, etc. …
176
+ }
177
+ };
178
+
179
+ // ─── Initialize scene ───────────────────────────────────────────────────
180
+ init();
181
+ </script>
182
+ </head>
183
+ <body>
184
+ <canvas id="canvas"></canvas>
185
+ <!-- your existing teleportPlayer, getSaveDataAndPosition hooks, etc. -->
186
  </body>
187
  </html>