sd4m commited on
Commit
ebef549
·
verified ·
1 Parent(s): d8434c0

Create scene.js

Browse files
Files changed (1) hide show
  1. scene.js +123 -0
scene.js ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // /src/three/scene.js
2
+
3
+ import * as THREE from 'three';
4
+
5
+ export class MarsScene {
6
+ constructor(containerEl, options = {}) {
7
+ this.container = containerEl;
8
+ this.width = containerEl.clientWidth;
9
+ this.height = containerEl.clientHeight;
10
+ this.scene = new THREE.Scene();
11
+
12
+ this.camera = new THREE.PerspectiveCamera(45, this.width / this.height, 0.1, 100);
13
+ this.camera.position.set(0, 0, 2.5);
14
+
15
+ this.renderer = new THREE.WebGLRenderer({ antialias: true });
16
+ this.renderer.setSize(this.width, this.height);
17
+ this.container.appendChild(this.renderer.domElement);
18
+
19
+ this._setupLights();
20
+ this._loadMarsTexture(options.marsUrl).then(texture => {
21
+ this._makeMars(texture);
22
+ }).catch(err => {
23
+ console.error('Error cargando textura Marte', err);
24
+ // fallback: color material
25
+ const mat = new THREE.MeshStandardMaterial({ color: 0x884400 });
26
+ this._makeMars(mat);
27
+ });
28
+
29
+ this._makeStarfield(1000);
30
+
31
+ this.rotationSpeed = 0.01; // rad/s
32
+
33
+ window.addEventListener('resize', () => this._onResize());
34
+
35
+ this.lastTime = performance.now();
36
+ this._animate();
37
+ }
38
+
39
+ _setupLights() {
40
+ const ambient = new THREE.AmbientLight(0xffffff, 0.5);
41
+ this.scene.add(ambient);
42
+ const dir = new THREE.DirectionalLight(0xffffff, 0.8);
43
+ dir.position.set(5, 5, 5);
44
+ this.scene.add(dir);
45
+ }
46
+
47
+ async _loadMarsTexture(url) {
48
+ const loader = new THREE.TextureLoader();
49
+ return new Promise((resolve, reject) => {
50
+ loader.load(
51
+ url,
52
+ tex => {
53
+ tex.encoding = THREE.sRGBEncoding;
54
+ resolve(tex);
55
+ },
56
+ undefined,
57
+ err => {
58
+ reject(err);
59
+ }
60
+ );
61
+ });
62
+ }
63
+
64
+ _makeMars(textureOrMaterial) {
65
+ let mat;
66
+ if (textureOrMaterial instanceof THREE.Texture) {
67
+ mat = new THREE.MeshStandardMaterial({ map: textureOrMaterial });
68
+ } else {
69
+ mat = textureOrMaterial;
70
+ }
71
+ const geo = new THREE.SphereGeometry(1, 64, 64);
72
+ this.marsMesh = new THREE.Mesh(geo, mat);
73
+ this.scene.add(this.marsMesh);
74
+ }
75
+
76
+ _makeStarfield(count) {
77
+ const geom = new THREE.BufferGeometry();
78
+ const positions = new Float32Array(count * 3);
79
+ for (let i = 0; i < count; i++) {
80
+ const r = THREE.MathUtils.randFloat(5, 20);
81
+ const theta = THREE.MathUtils.randFloatSpread(360);
82
+ const phi = THREE.MathUtils.randFloatSpread(360);
83
+ const x = r * Math.sin(theta) * Math.cos(phi);
84
+ const y = r * Math.sin(theta) * Math.sin(phi);
85
+ const z = r * Math.cos(theta);
86
+ positions[3*i] = x;
87
+ positions[3*i+1] = y;
88
+ positions[3*i+2] = z;
89
+ }
90
+ geom.setAttribute('position', new THREE.BufferAttribute(positions, 3));
91
+ const mat = new THREE.PointsMaterial({ color: 0xffffff, size: 0.02 });
92
+ const stars = new THREE.Points(geom, mat);
93
+ this.scene.add(stars);
94
+ }
95
+
96
+ _onResize() {
97
+ this.width = this.container.clientWidth;
98
+ this.height = this.container.clientHeight;
99
+ this.camera.aspect = this.width / this.height;
100
+ this.camera.updateProjectionMatrix();
101
+ this.renderer.setSize(this.width, this.height);
102
+ }
103
+
104
+ _animate() {
105
+ requestAnimationFrame(() => this._animate());
106
+ const now = performance.now();
107
+ const dt = (now - this.lastTime) / 1000;
108
+ this.lastTime = now;
109
+ if (this.marsMesh) {
110
+ this.marsMesh.rotation.y += this.rotationSpeed * dt;
111
+ }
112
+ this.renderer.render(this.scene, this camera);
113
+ }
114
+
115
+ // Exponer método para “limpiar” (quizás animar o cambiar material)
116
+ showCleanState() {
117
+ if (this.marsMesh && this.marsMesh.material) {
118
+ // un shader o cambio leve: por ejemplo emitir luz o brillo
119
+ this.marsMesh.material.emissive = new THREE.Color(0x003300);
120
+ this.marsMesh.material.emissiveIntensity = 0.2;
121
+ }
122
+ }
123
+ }