morfeo 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +2 -1
- package/lib/config.mjs +3 -1
- package/lib/diccionario.mjs +6 -1
- package/lib/recursos.mjs +2 -1
- package/package.json +1 -1
- package/remotion/kit/tres.tsx +4 -1
- package/remotion/motor/objetos-varios.tsx +226 -0
package/index.d.ts
CHANGED
|
@@ -31,7 +31,8 @@ export type Objeto3D = 'corazon' | 'estrella' | 'rayo' | 'diamante' | 'trofeo' |
|
|
|
31
31
|
| 'valvula' | 'grifo' | 'tinaco' | 'calentador' | 'bomba' | 'alcantarilla' | 'codo' | 'interruptor' | 'enchufe' | 'tablero' | 'medidor' | 'transformador' | 'poste' | 'bateria' | 'turbina' | 'torre_electrica' | 'aire' | 'chip' | 'placa' | 'resistor' | 'capacitor' | 'led' | 'disco_duro' | 'tarjeta_grafica' | 'disipador' | 'ram' | 'router' | 'servidor' | 'fuente_poder' | 'engrane' | 'tornillo' | 'tuerca' | 'motor' | 'resorte' | 'piston'
|
|
32
32
|
| 'atomo' | 'molecula' | 'adn' | 'celula' | 'virus' | 'cerebro' | 'neurona' | 'pulmon' | 'ojo' | 'diente' | 'hueso' | 'jeringa' | 'matraz' | 'telescopio' | 'iman' | 'sol' | 'tierra' | 'volcan' | 'tornado' | 'iceberg' | 'agujero_negro' | 'disco' | 'usb' | 'tarjeta_sd' | 'cable_hdmi' | 'microfono' | 'visor_vr' | 'cargador' | 'dron' | 'tanque_gas' | 'calentador_solar' | 'termostato' | 'detector_humo' | 'camara_seguridad' | 'antena_celular' | 'presa' | 'torre_enfriamiento' | 'ascensor' | 'fusible' | 'fibra_optica' | 'buzon' | 'autobus' | 'helicoptero' | 'submarino' | 'bicicleta' | 'lapiz' | 'regla' | 'dado' | 'ancla' | 'paraguas'
|
|
33
33
|
| 'guitarra' | 'piano' | 'tambor' | 'trompeta' | 'zapato' | 'camisa' | 'pulpo' | 'medusa' | 'tortuga' | 'pajaro' | 'buho' | 'moto' | 'pesa' | 'caminadora' | 'raqueta' | 'silbato' | 'golf' | 'tijeras' | 'mapa' | 'sobre' | 'tetera' | 'periodico' | 'pasaporte' | 'ropero' | 'tarjeta' | 'alcancia' | 'grafica' | 'calculadora' | 'pluma' | 'diploma' | 'birrete' | 'estetoscopio' | 'gota' | 'ramen' | 'planta_tratamiento' | 'refineria' | 'pozo_petrolero' | 'subestacion' | 'fosa_septica' | 'tubo_pvc' | 'granero' | 'parada' | 'hospital' | 'galaxia' | 'cometa' | 'lluvia' | 'fosil' | 'wifi' | 'huella' | 'telarana' | 'arbol_navidad'
|
|
34
|
-
| 'lago' | 'burbuja' | 'codigo' | 'musculo' | 'doctor' | 'bicicleta_estatica' | 'confeti' | 'registro' | 'cable_submarino'
|
|
34
|
+
| 'lago' | 'burbuja' | 'codigo' | 'musculo' | 'doctor' | 'bicicleta_estatica' | 'confeti' | 'registro' | 'cable_submarino'
|
|
35
|
+
| 'control' | 'consola' | 'cartucho' | 'audifonos' | 'cronometro' | 'termometro' | 'pincel' | 'cartera' | 'caja_fuerte' | 'pastilla' | 'fuegos_artificiales' | 'etiqueta';
|
|
35
36
|
|
|
36
37
|
/** Momento: segundos desde que empieza la escena, una palabra de `say` ("orcas"), "voz", "fin", o "palabra+0.3". */
|
|
37
38
|
export type Momento = number | string;
|
package/lib/config.mjs
CHANGED
|
@@ -33,7 +33,7 @@ export const ESCENARIOS = ['bosque', 'cuarto', 'departamento', 'tunel', 'pasillo
|
|
|
33
33
|
export const FORMAS_3D = ['moneda', 'billete', 'lingote', 'cubo', 'esfera', 'corazon', 'estrella', 'rayo', 'diamante', 'trofeo', 'cohete', 'foco', 'reloj', 'planeta', 'arbol', 'nube', 'regalo', 'llave', 'candado', 'casa', 'libro', 'globo', 'medalla', 'escudo', 'pin', 'tuberia', 'muro', 'viga', 'columna', 'escalera', 'losa', 'tanque', 'suelo',
|
|
34
34
|
'valvula', 'grifo', 'tinaco', 'calentador', 'bomba', 'alcantarilla', 'codo', 'interruptor', 'enchufe', 'tablero', 'medidor', 'transformador', 'poste', 'bateria', 'turbina', 'torre_electrica', 'aire', 'chip', 'placa', 'resistor', 'capacitor', 'led', 'disco_duro', 'tarjeta_grafica', 'disipador', 'ram', 'router', 'servidor', 'fuente_poder', 'engrane', 'tornillo', 'tuerca', 'motor', 'resorte', 'piston',
|
|
35
35
|
'atomo', 'molecula', 'adn', 'celula', 'virus', 'cerebro', 'neurona', 'pulmon', 'ojo', 'diente', 'hueso', 'jeringa', 'matraz', 'telescopio', 'iman', 'sol', 'tierra', 'volcan', 'tornado', 'iceberg', 'agujero_negro', 'disco', 'usb', 'tarjeta_sd', 'cable_hdmi', 'microfono', 'visor_vr', 'cargador', 'dron', 'tanque_gas', 'calentador_solar', 'termostato', 'detector_humo', 'camara_seguridad', 'antena_celular', 'presa', 'torre_enfriamiento', 'ascensor', 'fusible', 'fibra_optica', 'buzon', 'autobus', 'helicoptero', 'submarino', 'bicicleta', 'lapiz', 'regla', 'dado', 'ancla', 'paraguas',
|
|
36
|
-
'guitarra', 'piano', 'tambor', 'trompeta', 'zapato', 'camisa', 'pulpo', 'medusa', 'tortuga', 'pajaro', 'buho', 'moto', 'pesa', 'caminadora', 'raqueta', 'silbato', 'golf', 'tijeras', 'mapa', 'sobre', 'tetera', 'periodico', 'pasaporte', 'ropero', 'tarjeta', 'alcancia', 'grafica', 'calculadora', 'pluma', 'diploma', 'birrete', 'estetoscopio', 'gota', 'ramen', 'planta_tratamiento', 'refineria', 'pozo_petrolero', 'subestacion', 'fosa_septica', 'tubo_pvc', 'granero', 'parada', 'hospital', 'galaxia', 'cometa', 'lluvia', 'fosil', 'wifi', 'huella', 'telarana', 'arbol_navidad', 'lago', 'burbuja', 'codigo', 'musculo', 'doctor', 'bicicleta_estatica', 'confeti', 'registro', 'cable_submarino'];
|
|
36
|
+
'guitarra', 'piano', 'tambor', 'trompeta', 'zapato', 'camisa', 'pulpo', 'medusa', 'tortuga', 'pajaro', 'buho', 'moto', 'pesa', 'caminadora', 'raqueta', 'silbato', 'golf', 'tijeras', 'mapa', 'sobre', 'tetera', 'periodico', 'pasaporte', 'ropero', 'tarjeta', 'alcancia', 'grafica', 'calculadora', 'pluma', 'diploma', 'birrete', 'estetoscopio', 'gota', 'ramen', 'planta_tratamiento', 'refineria', 'pozo_petrolero', 'subestacion', 'fosa_septica', 'tubo_pvc', 'granero', 'parada', 'hospital', 'galaxia', 'cometa', 'lluvia', 'fosil', 'wifi', 'huella', 'telarana', 'arbol_navidad', 'lago', 'burbuja', 'codigo', 'musculo', 'doctor', 'bicicleta_estatica', 'confeti', 'registro', 'cable_submarino', 'control', 'consola', 'cartucho', 'audifonos', 'cronometro', 'termometro', 'pincel', 'cartera', 'caja_fuerte', 'pastilla', 'fuegos_artificiales', 'etiqueta'];
|
|
37
37
|
export const PROVEEDORES_VOZ = ['kokoro', 'elevenlabs', 'openai'];
|
|
38
38
|
export const MUSICAS = ['lofi', 'lofi2', 'chillpop', 'synth', 'house', 'ballad', 'trap'];
|
|
39
39
|
|
|
@@ -247,6 +247,8 @@ function validarCapas(capas, donde, err, comps) {
|
|
|
247
247
|
}
|
|
248
248
|
if (c.tipo === 'dividida') for (const lado of ['izq', 'der', 'arriba', 'abajo']) if (c[lado]?.capas) validarCapas(c[lado].capas, `${d}, ${lado}`, err, comps);
|
|
249
249
|
if (c.tipo === 'linea' && (!Array.isArray(c.hitos) || !c.hitos.length)) err(`${d}: \`linea\` necesita \`hitos\`: [{anio: 1963, texto: '…', en: 'palabra'}]`);
|
|
250
|
+
// `tamano` es una escala del objeto dentro de su recuadro (1 = normal); el tamaño en pantalla es `ancho`
|
|
251
|
+
if ((c.tipo === 'modelo' || c.tipo === 'recurso') && Number(c.tamano) > 10) err(`${d}: \`tamano: ${c.tamano}\` es la escala del objeto (1 = normal, 2 = el doble): con eso la cámara queda dentro. Para el tamaño en pantalla usa \`ancho\` (en px).`);
|
|
250
252
|
if (c.tipo === 'cintillo' && !c.nombre) err(`${d}: \`cintillo\` necesita \`nombre\``);
|
|
251
253
|
if (c.tipo === 'llamada' && c.estado != null && !['entrante', 'curso', 'terminada'].includes(c.estado)) err(`${d}: estado "${c.estado}" no existe (entrante, curso o terminada)`);
|
|
252
254
|
if (c.tipo === 'tierra' && (!esNum(c.lat) || !esNum(c.lon))) err(`${d}: \`tierra\` necesita \`lat\` y \`lon\` (números)`);
|
package/lib/diccionario.mjs
CHANGED
|
@@ -186,13 +186,18 @@ export const PIEZAS = {
|
|
|
186
186
|
// lo que faltaba
|
|
187
187
|
lago: ['lago', 'laguna'], burbuja: ['burbuja'], codigo: ['codigo', 'programacion', 'codigo_fuente'], musculo: ['musculo', 'biceps', 'brazo_fuerte'], doctor: ['doctor', 'doctora', 'medico'],
|
|
188
188
|
bicicleta_estatica: ['bicicleta_estatica', 'bici_estatica', 'bicicleta_fija'], confeti: ['confeti'], registro: ['registro', 'registro_sanitario', 'caja_de_registro'], cable_submarino: ['cable_submarino'],
|
|
189
|
+
// videojuegos y objetos que la búsqueda resolvía mal (un control salía como una canasta de arcade)
|
|
190
|
+
control: ['control', 'control_de_videojuegos', 'mando', 'gamepad', 'joystick', 'videojuego'], consola: ['consola', 'consola_de_videojuegos'],
|
|
191
|
+
cartucho: ['cartucho', 'cartucho_de_videojuego'], audifonos: ['audifonos', 'auriculares', 'diadema'], cronometro: ['cronometro'],
|
|
192
|
+
termometro: ['termometro', 'temperatura', 'fiebre'], pincel: ['pincel', 'brocha'], cartera: ['cartera', 'billetera'], caja_fuerte: ['caja_fuerte'],
|
|
193
|
+
pastilla: ['pastilla', 'capsula', 'medicina', 'medicamento'], fuegos_artificiales: ['fuegos_artificiales', 'pirotecnia'], etiqueta: ['etiqueta', 'etiqueta_de_precio'],
|
|
189
194
|
};
|
|
190
195
|
const PIEZA_DE = new Map();
|
|
191
196
|
for (const [forma, terminos] of Object.entries(PIEZAS)) for (const t of terminos) PIEZA_DE.set(t, forma);
|
|
192
197
|
|
|
193
198
|
/** Formas básicas de Morfeo (objetos3d.tsx) por término: se usan solo si ninguna biblioteca tiene el objeto. */
|
|
194
199
|
const BASICAS = {corazon: ['corazon'], estrella: ['estrella'], rayo: ['rayo', 'electricidad'], diamante: ['diamante', 'gema'], trofeo: ['trofeo', 'copa'], cohete: ['cohete'], foco: ['foco', 'bombilla', 'foco_led'], reloj: ['reloj'],
|
|
195
|
-
planeta: ['planeta', 'marte', 'saturno'], arbol: ['arbol'], nube: ['nube'], regalo: ['regalo'], llave: ['llave'], candado: ['candado'], casa: ['casa'], libro: ['libro'], globo: ['globo'], medalla: ['medalla'], escudo: ['escudo'], tanque: ['cisterna']};
|
|
200
|
+
planeta: ['planeta', 'marte', 'saturno'], arbol: ['arbol'], nube: ['nube'], regalo: ['regalo'], llave: ['llave'], candado: ['candado'], casa: ['casa'], libro: ['libro'], globo: ['globo'], medalla: ['medalla'], escudo: ['escudo'], billete: ['billete', 'billetes', 'dinero'], tanque: ['cisterna']};
|
|
196
201
|
const BASICA_DE = new Map();
|
|
197
202
|
for (const [forma, terminos] of Object.entries(BASICAS)) for (const t of terminos) BASICA_DE.set(t, forma);
|
|
198
203
|
export function basicaDe(termino) {
|
package/lib/recursos.mjs
CHANGED
|
@@ -101,7 +101,8 @@ function puntaje(nombrePalabras, consulta) {
|
|
|
101
101
|
let p = 0;
|
|
102
102
|
for (const w of q) {
|
|
103
103
|
if (n.includes(w)) p += 10;
|
|
104
|
-
|
|
104
|
+
// variantes de la misma palabra ("pipe" / "pipes", "tree" / "trees"), no compuestas: "gamepad" no es "game"
|
|
105
|
+
else if (w.length >= 4 && n.some((x) => x.length >= 4 && Math.abs(x.length - w.length) <= 1 && (x.startsWith(w) || w.startsWith(x)))) p += 4;
|
|
105
106
|
else return 0;
|
|
106
107
|
}
|
|
107
108
|
if (n[n.length - 1] === q[q.length - 1]) p += 6; // "modular pipe" > "pipe wrench" al buscar "pipe"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "morfeo",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "Genera videos verticales animados (Remotion + Three.js) con voz, música y subtítulos, desde un guion en código o escrito por IA.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
package/remotion/kit/tres.tsx
CHANGED
|
@@ -270,7 +270,10 @@ const Post: React.FC<{post: Post3D; estado: Estado}> = ({post, estado}) => {
|
|
|
270
270
|
const dist = Math.hypot(estado.pos[0] - estado.mirar[0], estado.pos[1] - estado.mirar[1], estado.pos[2] - estado.mirar[2]);
|
|
271
271
|
const rango = typeof o.foco === 'number' ? o.foco : Math.max(1.2, dist * 0.55);
|
|
272
272
|
const efectos: React.ReactElement[] = [];
|
|
273
|
-
|
|
273
|
+
// `focusRange` se actualiza en vivo; `worldFocusRange` va en el useMemo de @react-three/postprocessing y, como la
|
|
274
|
+
// distancia cambia en cada cuadro, creaba un DepthOfFieldEffect nuevo por cuadro: en Windows (ANGLE) la GPU se
|
|
275
|
+
// quedaba sin recursos a los ~30 s de video (Shader Error en EffectMaterial y "reading 'alpha'" de null).
|
|
276
|
+
if (o.foco) efectos.push(<DepthOfField key="f" target={estado.mirar} focusRange={rango} bokehScale={4} resolutionScale={0.5} />);
|
|
274
277
|
if (o.miniatura) efectos.push(<TiltShift2 key="m" blur={0.12 * o.miniatura} taper={0.6} start={[0.5, 0.0]} end={[0.5, 1.0]} />);
|
|
275
278
|
if (o.brillo) efectos.push(<Bloom key="b" intensity={o.brillo} luminanceThreshold={0.85} luminanceSmoothing={0.2} mipmapBlur />);
|
|
276
279
|
if (o.vinieta) efectos.push(<Vignette key="v" offset={0.3} darkness={o.vinieta} />);
|
|
@@ -7,6 +7,8 @@ import * as THREE from 'three';
|
|
|
7
7
|
import {ACERO, Aro, C, E, LATON, ORO, Tubo, Y, type M, type V3} from './objetos-ingenieria';
|
|
8
8
|
import {Cono, Ov, azar} from './objetos-ciencia';
|
|
9
9
|
|
|
10
|
+
const easeOutCubic = (x: number) => 1 - (1 - Math.min(1, Math.max(0, x))) ** 3;
|
|
11
|
+
|
|
10
12
|
export const OBJETOS_VARIOS = [
|
|
11
13
|
// música
|
|
12
14
|
'guitarra', 'piano', 'tambor', 'trompeta',
|
|
@@ -24,6 +26,8 @@ export const OBJETOS_VARIOS = [
|
|
|
24
26
|
'galaxia', 'cometa', 'lluvia', 'fosil', 'wifi', 'huella', 'telarana', 'arbol_navidad',
|
|
25
27
|
// lo que faltaba
|
|
26
28
|
'lago', 'burbuja', 'codigo', 'musculo', 'doctor', 'bicicleta_estatica', 'confeti', 'registro', 'cable_submarino',
|
|
29
|
+
// videojuegos y objetos que la búsqueda resolvía mal
|
|
30
|
+
'control', 'consola', 'cartucho', 'audifonos', 'cronometro', 'termometro', 'pincel', 'cartera', 'caja_fuerte', 'pastilla', 'fuegos_artificiales', 'etiqueta',
|
|
27
31
|
] as const;
|
|
28
32
|
|
|
29
33
|
const MADERA = {c: '#B8793F', r: 0.6};
|
|
@@ -1010,6 +1014,228 @@ export const ObjetoVario: React.FC<{forma: string; t: number; opciones?: Record<
|
|
|
1010
1014
|
</group>
|
|
1011
1015
|
);
|
|
1012
1016
|
}
|
|
1017
|
+
// ------------------------------------------------------------ videojuegos y objetos que faltaban
|
|
1018
|
+
case 'control': {
|
|
1019
|
+
const cuerpo = k('#2B2E36');
|
|
1020
|
+
const pulsa = (i: number) => (Math.sin(t * 3 - i * 1.4) > 0.85 ? 1 : 0);
|
|
1021
|
+
return (
|
|
1022
|
+
// los botones miran a la cámara: el control se inclina hacia adelante, no se ve de canto
|
|
1023
|
+
<group rotation={[1.15, 0, 0]} position={[0, 0.05, 0]} scale={1.15}>
|
|
1024
|
+
<C s={[1.5, 0.26, 0.72]} c={cuerpo} r={0.5} />
|
|
1025
|
+
{[-1, 1].map((l) => (
|
|
1026
|
+
<group key={l}>
|
|
1027
|
+
<Ov p={[l * 0.72, -0.02, -0.08]} s={[0.36, 0.17, 0.42]} c={cuerpo} r={0.5} />
|
|
1028
|
+
<Ov p={[l * 0.86, -0.04, 0.38]} s={[0.24, 0.15, 0.4]} rot={[0, l * 0.35, 0]} c={cuerpo} r={0.5} />
|
|
1029
|
+
<C p={[l * 0.62, 0.02, -0.42]} s={[0.36, 0.14, 0.12]} c="#1B1C22" r={0.5} />
|
|
1030
|
+
</group>
|
|
1031
|
+
))}
|
|
1032
|
+
{/* cruceta */}
|
|
1033
|
+
<C p={[-0.55, 0.15, -0.06]} s={[0.26, 0.06, 0.08]} c="#1B1C22" r={0.5} />
|
|
1034
|
+
<C p={[-0.55, 0.15, -0.06]} s={[0.08, 0.06, 0.26]} c="#1B1C22" r={0.5} />
|
|
1035
|
+
{/* botones */}
|
|
1036
|
+
{([[0.55, -0.18, '#3D7BFF'], [0.55, 0.06, '#2EC27E'], [0.43, -0.06, '#FFD23F'], [0.67, -0.06, '#E5484D']] as [number, number, string][]).map(([x, z, c], i) => (
|
|
1037
|
+
<Y key={i} p={[x, 0.15 - pulsa(i) * 0.025, z]} rad={0.055} h={0.07} c={c} e={0.2 + pulsa(i) * 0.6} r={0.35} />
|
|
1038
|
+
))}
|
|
1039
|
+
{/* palancas */}
|
|
1040
|
+
{([[-0.28, 0.2], [0.28, 0.2]] as [number, number][]).map(([x, z], i) => (
|
|
1041
|
+
<group key={i} rotation={[Math.sin(t * 1.3 + i) * 0.18, 0, Math.cos(t * 1.1 + i) * 0.18]} position={[x, 0.13, z]}>
|
|
1042
|
+
<Y rad={0.12} h={0.06} c="#1B1C22" r={0.6} />
|
|
1043
|
+
<Y p={[0, 0.07, 0]} rad={0.04} h={0.12} c="#3A3D45" r={0.5} />
|
|
1044
|
+
<Y p={[0, 0.14, 0]} rad={[0.1, 0.11]} h={0.05} c="#3A3D45" r={0.7} />
|
|
1045
|
+
</group>
|
|
1046
|
+
))}
|
|
1047
|
+
<Y p={[0, 0.14, -0.2]} rad={0.05} h={0.03} c="#F7F5F0" e={0.6} />
|
|
1048
|
+
</group>
|
|
1049
|
+
);
|
|
1050
|
+
}
|
|
1051
|
+
case 'consola':
|
|
1052
|
+
return (
|
|
1053
|
+
<group rotation={[0.3, -0.45, 0]} position={[0, -0.1, 0]}>
|
|
1054
|
+
<C s={[1.9, 0.42, 1.25]} c={k('#E9E7E2')} r={0.45} />
|
|
1055
|
+
<C p={[0, 0.215, 0]} s={[1.92, 0.02, 1.27]} c="#1B1C22" r={0.5} />
|
|
1056
|
+
<C p={[0.1, 0.32, -0.05]} s={[1.6, 0.2, 1.05]} c={k('#E9E7E2')} r={0.45} />
|
|
1057
|
+
<C p={[0, 0.06, 0.63]} s={[1.0, 0.04, 0.02]} c="#1B1C22" />
|
|
1058
|
+
<C p={[-0.7, 0.06, 0.63]} s={[0.12, 0.06, 0.02]} c="#3D7BFF" e={0.5 + 0.4 * Math.sin(t * 2)} />
|
|
1059
|
+
{[-0.25, 0.05].map((x) => (
|
|
1060
|
+
<C key={x} p={[x + 0.5, -0.06, 0.63]} s={[0.18, 0.06, 0.02]} c="#1B1C22" />
|
|
1061
|
+
))}
|
|
1062
|
+
{Array.from({length: 7}, (_, i) => (
|
|
1063
|
+
<C key={i} p={[-0.95, 0.12 - i * 0.05, -0.3 + (i % 2) * 0.02]} s={[0.02, 0.025, 0.6]} c="#9A9DA4" />
|
|
1064
|
+
))}
|
|
1065
|
+
</group>
|
|
1066
|
+
);
|
|
1067
|
+
case 'cartucho':
|
|
1068
|
+
return (
|
|
1069
|
+
<group rotation={[-0.15, -0.3, 0.08]}>
|
|
1070
|
+
<C s={[1.3, 1.45, 0.24]} c={k('#7C7F87')} r={0.55} />
|
|
1071
|
+
<C p={[0, 0.64, 0]} s={[1.18, 0.18, 0.26]} c={k('#7C7F87')} r={0.55} />
|
|
1072
|
+
{[-0.3, -0.18, -0.06, 0.06, 0.18, 0.3].map((x) => (
|
|
1073
|
+
<C key={x} p={[x, 0.64, 0.135]} s={[0.07, 0.12, 0.01]} c="#5E6168" />
|
|
1074
|
+
))}
|
|
1075
|
+
<C p={[0, 0.02, 0.125]} s={[1.0, 0.9, 0.01]} c="#F7F5F0" r={0.6} />
|
|
1076
|
+
<C p={[0, 0.2, 0.135]} s={[0.86, 0.4, 0.01]} c="#E5484D" e={0.15} r={0.5} />
|
|
1077
|
+
<C p={[0, -0.18, 0.135]} s={[0.6, 0.08, 0.01]} c="#1B1C22" />
|
|
1078
|
+
<C p={[0, -0.32, 0.135]} s={[0.4, 0.05, 0.01]} c="#9A9DA4" />
|
|
1079
|
+
<C p={[0, -0.75, 0]} s={[0.9, 0.06, 0.16]} c="#3A3D45" />
|
|
1080
|
+
{Array.from({length: 10}, (_, i) => (
|
|
1081
|
+
<C key={i} p={[-0.36 + i * 0.08, -0.75, 0.085]} s={[0.04, 0.05, 0.01]} {...ORO} />
|
|
1082
|
+
))}
|
|
1083
|
+
<C p={[0.5, 0.45, 0.13]} s={[0.12, 0.12, 0.01]} c="#5E6168" />
|
|
1084
|
+
</group>
|
|
1085
|
+
);
|
|
1086
|
+
case 'audifonos':
|
|
1087
|
+
return (
|
|
1088
|
+
<group rotation={[0.1, -0.35, 0]}>
|
|
1089
|
+
<Aro p={[0, 0.15, 0]} rad={0.78} tubo={0.075} arco={Math.PI} c={k('#2B2E36')} r={0.45} />
|
|
1090
|
+
<Aro p={[0, 0.15, 0]} rad={0.73} tubo={0.05} arco={Math.PI * 0.7} rot={[0, 0, Math.PI * 0.15]} c="#E5484D" r={0.6} />
|
|
1091
|
+
{[-1, 1].map((l) => (
|
|
1092
|
+
<group key={l} position={[l * 0.78, -0.12, 0]}>
|
|
1093
|
+
<C p={[0, 0.2, 0]} s={[0.08, 0.22, 0.1]} {...ACERO} />
|
|
1094
|
+
<Y eje="x" rad={0.34} h={0.22} c={k('#2B2E36')} r={0.45} />
|
|
1095
|
+
<Y eje="x" p={[-l * 0.13, 0, 0]} rad={0.3} h={0.08} c="#3A3D45" r={0.9} />
|
|
1096
|
+
<Y eje="x" p={[l * 0.115, 0, 0]} rad={0.2} h={0.02} c="#E5484D" r={0.5} e={0.15} />
|
|
1097
|
+
</group>
|
|
1098
|
+
))}
|
|
1099
|
+
</group>
|
|
1100
|
+
);
|
|
1101
|
+
case 'cronometro': {
|
|
1102
|
+
const vuelta = (t * 0.5) % 1;
|
|
1103
|
+
return (
|
|
1104
|
+
<group rotation={[0.08, -0.2, 0]}>
|
|
1105
|
+
<Y eje="z" rad={0.85} h={0.26} c={k('#C9CED6')} m={0.8} r={0.3} seg={40} />
|
|
1106
|
+
<Y eje="z" p={[0, 0, 0.12]} rad={0.75} h={0.04} c="#F7F5F0" r={0.5} seg={40} />
|
|
1107
|
+
{Array.from({length: 12}, (_, i) => {
|
|
1108
|
+
const a = (i / 12) * Math.PI * 2;
|
|
1109
|
+
return <C key={i} p={[Math.sin(a) * 0.62, Math.cos(a) * 0.62, 0.15]} rot={[0, 0, -a]} s={[0.03, i % 3 === 0 ? 0.13 : 0.07, 0.01]} c="#1B1C22" />;
|
|
1110
|
+
})}
|
|
1111
|
+
<group position={[0, 0, 0.16]} rotation={[0, 0, -vuelta * Math.PI * 2]}>
|
|
1112
|
+
<C p={[0, 0.27, 0]} s={[0.035, 0.56, 0.01]} c="#E5484D" e={0.3} />
|
|
1113
|
+
</group>
|
|
1114
|
+
<Y eje="z" p={[0, 0, 0.17]} rad={0.05} h={0.02} c="#1B1C22" />
|
|
1115
|
+
<Y p={[0, 0.98, 0]} rad={0.1} h={0.18} c={k('#C9CED6')} m={0.8} r={0.3} />
|
|
1116
|
+
<Y p={[0, 1.1, 0]} rad={0.17} h={0.08} c="#E5484D" r={0.4} />
|
|
1117
|
+
<Aro p={[0, 1.3, 0]} rad={0.14} tubo={0.04} c={k('#C9CED6')} m={0.8} r={0.3} />
|
|
1118
|
+
<Y p={[0.62, 0.62, 0]} rot={[0, 0, -Math.PI / 4]} rad={0.07} h={0.16} c={k('#C9CED6')} m={0.8} r={0.3} />
|
|
1119
|
+
</group>
|
|
1120
|
+
);
|
|
1121
|
+
}
|
|
1122
|
+
case 'termometro': {
|
|
1123
|
+
const nivel = 0.45 + 0.35 * (0.5 + 0.5 * Math.sin(t * 1.2));
|
|
1124
|
+
return (
|
|
1125
|
+
<group rotation={[0, 0, -0.18]}>
|
|
1126
|
+
<Y p={[0, 0.25, 0]} rad={0.15} h={1.9} c="#DDEAF5" o={0.45} r={0.1} />
|
|
1127
|
+
<E p={[0, -0.82, 0]} rad={0.28} c={k('#E5484D')} r={0.3} e={0.2} />
|
|
1128
|
+
<Y p={[0, -0.62 + nivel * 0.8, 0]} rad={0.07} h={0.4 + nivel * 1.6} c={k('#E5484D')} e={0.25} r={0.3} />
|
|
1129
|
+
{Array.from({length: 8}, (_, i) => (
|
|
1130
|
+
<C key={i} p={[0.17, -0.35 + i * 0.18, 0]} s={[i % 2 ? 0.05 : 0.1, 0.018, 0.02]} c="#1B1C22" />
|
|
1131
|
+
))}
|
|
1132
|
+
<Y p={[0, 1.22, 0]} rad={0.15} h={0.05} c="#C9CED6" m={0.8} />
|
|
1133
|
+
</group>
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
1136
|
+
case 'pincel':
|
|
1137
|
+
return (
|
|
1138
|
+
<group rotation={[0, 0, -0.7]}>
|
|
1139
|
+
<Y p={[0, 0.55, 0]} rad={[0.07, 0.1]} h={1.3} c={k('#C0392B')} r={0.35} />
|
|
1140
|
+
<Y p={[0, -0.22, 0]} rad={[0.1, 0.11]} h={0.3} c="#C9CED6" m={0.85} r={0.3} />
|
|
1141
|
+
<Y p={[0, -0.52, 0]} rad={[0.11, 0.03]} h={0.36} c="#3B2A1E" r={0.9} />
|
|
1142
|
+
<Y p={[0, -0.69, 0]} rad={[0.035, 0.005]} h={0.08} c="#3D7BFF" r={0.2} e={0.2} />
|
|
1143
|
+
<E p={[0.2, -0.95, 0]} rad={0.05} c="#3D7BFF" r={0.2} />
|
|
1144
|
+
</group>
|
|
1145
|
+
);
|
|
1146
|
+
case 'cartera':
|
|
1147
|
+
return (
|
|
1148
|
+
<group rotation={[0.3, -0.4, 0]}>
|
|
1149
|
+
<C s={[1.5, 1.0, 0.22]} c={k('#7A4A2A')} r={0.75} />
|
|
1150
|
+
<C p={[0, 0.3, 0.12]} s={[1.5, 0.42, 0.04]} c={k('#7A4A2A')} r={0.75} />
|
|
1151
|
+
<C p={[0, 0.2, 0.15]} s={[1.44, 0.02, 0.01]} c="#4E2E1A" />
|
|
1152
|
+
<C p={[0.42, 0.62, 0.02]} s={[0.55, 0.3, 0.12]} c="#6BBF59" r={0.8} />
|
|
1153
|
+
<C p={[-0.25, 0.58, 0.06]} s={[0.6, 0.22, 0.04]} c="#3D7BFF" r={0.4} />
|
|
1154
|
+
<Y eje="z" p={[0.55, 0.3, 0.15]} rad={0.07} h={0.03} {...LATON} />
|
|
1155
|
+
</group>
|
|
1156
|
+
);
|
|
1157
|
+
case 'caja_fuerte': {
|
|
1158
|
+
const gira = Math.sin(t * 1.4) * 1.2;
|
|
1159
|
+
return (
|
|
1160
|
+
<group rotation={[0.1, -0.45, 0]}>
|
|
1161
|
+
<C s={[1.5, 1.6, 1.3]} c={k('#4A4F59')} m={0.6} r={0.4} />
|
|
1162
|
+
<C p={[0, 0, 0.66]} s={[1.24, 1.34, 0.04]} c={k('#5B616C')} m={0.6} r={0.4} />
|
|
1163
|
+
<group position={[0.05, 0.12, 0.7]} rotation={[0, 0, gira]}>
|
|
1164
|
+
<Y eje="z" rad={0.28} h={0.08} c="#C9CED6" m={0.85} r={0.25} seg={32} />
|
|
1165
|
+
{Array.from({length: 10}, (_, i) => (
|
|
1166
|
+
<C key={i} p={[Math.sin((i / 10) * Math.PI * 2) * 0.22, Math.cos((i / 10) * Math.PI * 2) * 0.22, 0.045]} rot={[0, 0, -(i / 10) * Math.PI * 2]} s={[0.02, 0.06, 0.01]} c="#1B1C22" />
|
|
1167
|
+
))}
|
|
1168
|
+
<Y eje="z" p={[0, 0, 0.06]} rad={0.08} h={0.06} c="#3A3D45" />
|
|
1169
|
+
</group>
|
|
1170
|
+
<C p={[0.05, -0.38, 0.72]} s={[0.5, 0.08, 0.08]} c="#C9CED6" m={0.85} r={0.25} />
|
|
1171
|
+
{[-0.45, 0.45].map((y) => (
|
|
1172
|
+
<C key={y} p={[-0.66, y, 0.6]} s={[0.08, 0.22, 0.12]} c="#2B2E36" m={0.6} r={0.4} />
|
|
1173
|
+
))}
|
|
1174
|
+
</group>
|
|
1175
|
+
);
|
|
1176
|
+
}
|
|
1177
|
+
case 'pastilla':
|
|
1178
|
+
return (
|
|
1179
|
+
<group rotation={[0.3, 0.2, -0.6 + Math.sin(t * 1.2) * 0.05]}>
|
|
1180
|
+
<Y p={[0, 0.32, 0]} rad={0.36} h={0.64} c={k('#E5484D')} r={0.25} seg={32} />
|
|
1181
|
+
<E p={[0, 0.64, 0]} rad={0.36} c={k('#E5484D')} r={0.25} />
|
|
1182
|
+
<Y p={[0, -0.32, 0]} rad={0.36} h={0.64} c="#F7F5F0" r={0.25} seg={32} />
|
|
1183
|
+
<E p={[0, -0.64, 0]} rad={0.36} c="#F7F5F0" r={0.25} />
|
|
1184
|
+
<Ov p={[-0.17, 0.45, 0.24]} s={[0.06, 0.22, 0.03]} c="#FFFFFF" o={0.7} e={0.5} />
|
|
1185
|
+
</group>
|
|
1186
|
+
);
|
|
1187
|
+
case 'fuegos_artificiales': {
|
|
1188
|
+
const colores = ['#FFD23F', '#E5484D', '#3D7BFF', '#2EC27E', '#C061CB'];
|
|
1189
|
+
return (
|
|
1190
|
+
<group>
|
|
1191
|
+
{[0, 1, 2].map((n) => {
|
|
1192
|
+
const f = (t * 0.4 + n * 0.34) % 1;
|
|
1193
|
+
const sube = Math.min(1, f / 0.3);
|
|
1194
|
+
const abre = Math.max(0, (f - 0.3) / 0.7);
|
|
1195
|
+
const centro: V3 = [-0.75 + n * 0.75, -1.0 + easeOutCubic(sube) * (1.55 + (n % 2) * 0.35), -n * 0.15];
|
|
1196
|
+
const c = colores[(n * 2 + 1) % colores.length];
|
|
1197
|
+
const r = easeOutCubic(abre) * (0.7 + (n % 2) * 0.15);
|
|
1198
|
+
const luz = Math.max(0, 1 - abre * 1.1);
|
|
1199
|
+
return (
|
|
1200
|
+
<group key={n}>
|
|
1201
|
+
{f < 0.3 ? (
|
|
1202
|
+
<group>
|
|
1203
|
+
<E p={centro} rad={0.06} c="#FFF2B0" e={1.2} />
|
|
1204
|
+
<C p={[centro[0], centro[1] - 0.18, centro[2]]} s={[0.03, 0.3, 0.03]} c="#FFB347" e={0.8} o={0.7} />
|
|
1205
|
+
</group>
|
|
1206
|
+
) : null}
|
|
1207
|
+
{abre > 0 ? (
|
|
1208
|
+
<group position={[centro[0], centro[1] - abre * abre * 0.3, centro[2]]}>
|
|
1209
|
+
{Array.from({length: 14}, (_, i) => {
|
|
1210
|
+
const a = (i / 14) * Math.PI * 2;
|
|
1211
|
+
return (
|
|
1212
|
+
<group key={i} rotation={[0, 0, a]}>
|
|
1213
|
+
<C p={[r * 0.82, 0, 0]} s={[Math.max(0.02, r * 0.38), 0.035, 0.035]} c={c} e={1.1 * luz} o={luz} />
|
|
1214
|
+
<E p={[r, 0, 0]} rad={0.07 * (0.4 + luz * 0.6)} c={i % 2 ? c : '#FFF2B0'} e={1.3 * luz} />
|
|
1215
|
+
</group>
|
|
1216
|
+
);
|
|
1217
|
+
})}
|
|
1218
|
+
<E rad={0.12 * luz} c="#FFFFFF" e={1.5} o={luz} />
|
|
1219
|
+
</group>
|
|
1220
|
+
) : null}
|
|
1221
|
+
</group>
|
|
1222
|
+
);
|
|
1223
|
+
})}
|
|
1224
|
+
</group>
|
|
1225
|
+
);
|
|
1226
|
+
}
|
|
1227
|
+
case 'etiqueta':
|
|
1228
|
+
return (
|
|
1229
|
+
<group rotation={[0, -0.3, 0.25 + Math.sin(t * 1.6) * 0.06]}>
|
|
1230
|
+
<mesh>
|
|
1231
|
+
<extrudeGeometry args={[(() => { const s = new THREE.Shape(); s.moveTo(-0.55, -0.75); s.lineTo(0.55, -0.75); s.lineTo(0.55, 0.45); s.lineTo(0, 0.9); s.lineTo(-0.55, 0.45); s.closePath(); const h = new THREE.Path(); h.absarc(0, 0.5, 0.11, 0, Math.PI * 2, true); s.holes.push(h); return s; })(), {depth: 0.06, bevelEnabled: false}]} />
|
|
1232
|
+
<meshStandardMaterial color={k('#FFD23F')} roughness={0.6} />
|
|
1233
|
+
</mesh>
|
|
1234
|
+
<C p={[0, -0.05, 0.065]} s={[0.7, 0.16, 0.01]} c="#1B1C22" />
|
|
1235
|
+
<C p={[0, -0.35, 0.065]} s={[0.45, 0.08, 0.01]} c="#1B1C22" />
|
|
1236
|
+
<Tubo pts={[[0, 0.5, 0.03], [0.15, 0.85, 0.05], [0.05, 1.2, 0.02]]} rad={0.02} c="#E5484D" r={0.6} />
|
|
1237
|
+
</group>
|
|
1238
|
+
);
|
|
1013
1239
|
default:
|
|
1014
1240
|
return null;
|
|
1015
1241
|
}
|