Skip to content

Commit add4620

Browse files
authored
Merge pull request #696 from SendellX/master
2 parents 3c99b59 + bc82237 commit add4620

21 files changed

+287
-0
lines changed

src/game/scenery/isometric/metadata/models.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { getParams } from '../../../../params';
1515
import { loadFx } from './fx/loader';
1616
import Game from '../../../Game';
1717
import { Fx } from './fx/Fx';
18+
import { createTwinklingStar } from '../misc/twinkling_star';
1819

1920
const exporter = new GLTFExporter();
2021

@@ -95,6 +96,47 @@ export async function loadFullSceneModel(
9596
}
9697
}
9798
});
99+
100+
if (entry === 117) {
101+
// Twinkling star effects for entry 117 (scene 173, Kurtz house)
102+
// Specs: pos (Vector3), size (scale), color (hex Color), speed (twinkle rate)
103+
const starSpecs = [
104+
{
105+
pos: new THREE.Vector3(41.3, 3.85, 35),
106+
size: 1.0,
107+
color: 0xefb810,
108+
speed: 1.514
109+
},
110+
{
111+
pos: new THREE.Vector3(41.17, 3.4, 35.5),
112+
size: 0.6,
113+
color: 0x3c341e,
114+
speed: 1.259
115+
}
116+
// Add more stars by adding additional objects to this array.
117+
];
118+
119+
for (const spec of starSpecs) {
120+
const { pos, size, color, speed } = spec;
121+
// Create a twinkling star (defined in ../misc/twinkling_star.ts)
122+
const starEffect = await createTwinklingStar(
123+
pos,
124+
new THREE.Color(color),
125+
size,
126+
speed
127+
);
128+
// Add the star's mesh to the scene
129+
threeObject.add(starEffect.threeObject);
130+
// Register the star's update function to animate its twinkle each frame
131+
effects.push({
132+
init: () => {}, // no extra initialization needed
133+
update: (_game, _scene, time) => {
134+
starEffect.update(time); // update star effect (uses time.elapsed in shader)
135+
}
136+
});
137+
}
138+
}
139+
98140
const mixer = new THREE.AnimationMixer(threeObject);
99141
applyAnimationUpdaters(threeObject, model.animations);
100142
each(model.animations, (clip) => {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
precision highp float;
2+
3+
// Varyings from the vertex shader
4+
varying float vIntensity;
5+
varying float vSparkle;
6+
varying vec2 vUv;
7+
8+
// Uniforms set via Three.js
9+
uniform sampler2D starTex;
10+
uniform vec3 uColor;
11+
uniform float time;
12+
uniform float uSpeed;
13+
14+
void main() {
15+
// Compute twinkle flicker factor
16+
float flicker = sin(time * uSpeed + vSparkle * 10.0) * vSparkle;
17+
float finalIntensity = vIntensity + flicker;
18+
19+
// Sample the star texture and apply the color tint
20+
vec4 tex = texture2D(starTex, vUv);
21+
vec3 invertedRGB = vec3(1.0) - tex.rgb;
22+
vec3 tinted = invertedRGB * uColor;
23+
24+
// Apply the final intensity to color and alpha
25+
vec4 color = vec4(tinted * finalIntensity, tex.a * finalIntensity);
26+
27+
// Discard nearly transparent pixels for cleaner edges
28+
if (color.a < 0.01) discard;
29+
30+
gl_FragColor = color;
31+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
precision highp float;
2+
3+
// Standard vertex attributes (not automatically provided in RawShaderMaterial)
4+
attribute vec3 position;
5+
attribute vec2 uv;
6+
7+
// Custom attributes for brightness and sparkle effect
8+
attribute float intensity;
9+
attribute float size;
10+
attribute float sparkle;
11+
12+
// Varyings to pass data to the fragment shader
13+
varying float vIntensity;
14+
varying float vSparkle;
15+
varying vec2 vUv;
16+
17+
// Transformation matrices (provided by Three.js)
18+
uniform mat4 modelViewMatrix;
19+
uniform mat4 projectionMatrix;
20+
21+
void main() {
22+
// Pass custom attribute values to the fragment shader via varyings
23+
vIntensity = intensity;
24+
vSparkle = sparkle;
25+
vUv = uv;
26+
27+
// Center UV coordinates at (0.5, 0.5) and scale by size
28+
vec2 centeredUV = uv - vec2(0.5);
29+
vec2 offset = centeredUV * size;
30+
31+
// Compute vertex position in camera space
32+
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
33+
34+
// Offset the X and Y position by the computed offset (billboard quad)
35+
mvPosition.xy += offset;
36+
37+
// Project the vertex to clip space
38+
gl_Position = projectionMatrix * mvPosition;
39+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import * as THREE from 'three';
2+
import STAR_VERT from './shaders/star_twinkle.vert.glsl';
3+
import STAR_FRAG from './shaders/star_twinkle.frag.glsl';
4+
5+
const loader = new THREE.TextureLoader();
6+
7+
/**
8+
* Create a twinkling star effect at a given position.
9+
* Returns an object with the star's Three.js mesh and an update function.
10+
*/
11+
export async function createTwinklingStar(
12+
position: THREE.Vector3,
13+
color: number | string | THREE.Color,
14+
size = 1.0,
15+
speed = 1.5
16+
) {
17+
// Load star texture (with alpha channel for transparency)
18+
const starTexture = await new Promise<THREE.Texture>((resolve) => {
19+
loader.load('images/stars/B_OPC1.png', resolve);
20+
});
21+
22+
// Create a RawShaderMaterial for the star using custom shaders
23+
const starMaterial = new THREE.RawShaderMaterial({
24+
vertexShader: STAR_VERT,
25+
fragmentShader: STAR_FRAG,
26+
uniforms: {
27+
starTex: { value: starTexture },
28+
uColor: { value: new THREE.Color(color) },
29+
time: { value: 0.0 },
30+
uSpeed: { value: speed }
31+
},
32+
transparent: true,
33+
blending: THREE.AdditiveBlending,
34+
depthWrite: false,
35+
side: THREE.FrontSide
36+
});
37+
38+
// Define star geometry as a quad (two triangles at the given position)
39+
const starGeo = new THREE.BufferGeometry();
40+
const positions: number[] = [];
41+
const uvs: number[] = [];
42+
const intensities: number[] = [];
43+
const sizes: number[] = [];
44+
const sparkles: number[] = [];
45+
46+
// Base attributes for the star
47+
const baseIntensity = 0.4; // base brightness intensity
48+
const baseSize = 0.1 * size; // base sprite size in world units
49+
const baseSparkle = 0.7; // base sparkle variation factor
50+
51+
// Add 6 vertices at the star position (two triangles forming a quad)
52+
for (let j = 0; j < 6; j += 1) {
53+
positions.push(position.x, position.y, position.z);
54+
intensities.push(baseIntensity);
55+
sizes.push(baseSize);
56+
sparkles.push(baseSparkle);
57+
}
58+
// Set UV coordinates for the two triangles (covering the full texture)
59+
uvs.push(
60+
0, 0,
61+
0, 1,
62+
1, 0,
63+
1, 1,
64+
1, 0,
65+
0, 1
66+
);
67+
68+
starGeo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
69+
starGeo.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));
70+
starGeo.setAttribute('intensity', new THREE.Float32BufferAttribute(intensities, 1));
71+
starGeo.setAttribute('size', new THREE.Float32BufferAttribute(sizes, 1));
72+
starGeo.setAttribute('sparkle', new THREE.Float32BufferAttribute(sparkles, 1));
73+
// Set the index buffer to form two triangles (0-1-2 and 3-4-5)
74+
starGeo.setIndex([5, 4, 3, 2, 1, 0]);
75+
76+
// Create the star mesh with its geometry and material
77+
const starMesh = new THREE.Mesh(starGeo, starMaterial);
78+
starMesh.name = 'twinkling_star';
79+
starMesh.frustumCulled = false; // always render (disable frustum culling)
80+
starMesh.renderOrder = 2; // draw after scene objects to avoid overlap
81+
82+
// Return the Three.js mesh and an update function for the twinkle animation
83+
return {
84+
threeObject: starMesh,
85+
update: (time: { elapsed: number }) => {
86+
// Update the time uniform to animate the flicker effect
87+
starMaterial.uniforms.time.value = time.elapsed;
88+
}
89+
};
90+
}

www/metadata/lba2/grids.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6250,6 +6250,20 @@
62506250
0,
62516251
6.123233995736766e-17
62526252
]
6253+
},
6254+
{
6255+
"name": "FI_053_liquor_bottle_and_mug.glb",
6256+
"position": {
6257+
"x": 41,
6258+
"y": 1.5,
6259+
"z": 31.5
6260+
},
6261+
"quaternion": [
6262+
0,
6263+
0.7071067811865475,
6264+
0,
6265+
0.7071067811865476
6266+
]
62536267
}
62546268
],
62556269
"patches": {
@@ -7317,6 +7331,12 @@
73177331
},
73187332
"14x1x37": {
73197333
"hide": true
7334+
},
7335+
"41x3x32": {
7336+
"hide": true
7337+
},
7338+
"41x4x32": {
7339+
"hide": true
73207340
}
73217341
}
73227342
},

www/metadata/lba2/layouts.json

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5285,6 +5285,16 @@
52855285
}
52865286
},
52875287
"15": {
5288+
"0": {
5289+
"replace": true,
5290+
"file": "FI_000_001_010_011_padded_armchair.glb",
5291+
"orientation": 0
5292+
},
5293+
"1": {
5294+
"replace": true,
5295+
"file": "FI_000_001_010_011_padded_armchair.glb",
5296+
"orientation": 1
5297+
},
52885298
"2": {
52895299
"replace": true,
52905300
"file": "FI_002_003_francos_building_wall.glb",
@@ -5320,6 +5330,26 @@
53205330
"file": "FI_008_francos_building_wall_round_corner.glb",
53215331
"orientation": 0
53225332
},
5333+
"9": {
5334+
"replace": true,
5335+
"file": "FI_009_padded_armchair_long.glb",
5336+
"orientation": 0
5337+
},
5338+
"10": {
5339+
"replace": true,
5340+
"file": "FI_000_001_010_011_padded_armchair.glb",
5341+
"orientation": 3
5342+
},
5343+
"11": {
5344+
"replace": true,
5345+
"file": "FI_000_001_010_011_padded_armchair.glb",
5346+
"orientation": 2
5347+
},
5348+
"12": {
5349+
"replace": true,
5350+
"file": "FI_012_padded_beanbag.glb",
5351+
"orientation": 0
5352+
},
53235353
"17": {
53245354
"replace": true,
53255355
"file": "FI_017_francos_building_wall_window_big.glb",
@@ -5340,6 +5370,11 @@
53405370
"file": "FI_020_francos_building_wall_window.glb",
53415371
"orientation": 0
53425372
},
5373+
"22": {
5374+
"replace": true,
5375+
"file": "FI_022_padded_stool.glb",
5376+
"orientation": 0
5377+
},
53435378
"23": {
53445379
"replace": true,
53455380
"file": "FI_023_francos_doorframe.glb",
@@ -5350,6 +5385,11 @@
53505385
"file": "FI_024_francos_doorframe.glb",
53515386
"orientation": 0
53525387
},
5388+
"25": {
5389+
"replace": true,
5390+
"file": "FI_025_round_table.glb",
5391+
"orientation": 0
5392+
},
53535393
"26": {
53545394
"replace": true,
53555395
"file": "FI_026_ice_creams_and_cup.glb",
@@ -5485,11 +5525,26 @@
54855525
"file": "FI_069_short_stool.glb",
54865526
"orientation": 0
54875527
},
5528+
"70": {
5529+
"replace": true,
5530+
"file": "FI_070_baby_cushion.glb",
5531+
"orientation": 0
5532+
},
5533+
"71": {
5534+
"replace": true,
5535+
"file": "FI_071_red_soup.glb",
5536+
"orientation": 0
5537+
},
54885538
"72": {
54895539
"replace": true,
54905540
"file": "FI_072_baby_bottles.glb",
54915541
"orientation": 0
54925542
},
5543+
"73": {
5544+
"replace": true,
5545+
"file": "FI_073_little_doll.glb",
5546+
"orientation": 0
5547+
},
54935548
"74": {
54945549
"replace": true,
54955550
"file": "FI_074_abacus.glb",
@@ -5515,6 +5570,11 @@
55155570
"file": "FI_079_big_candle.glb",
55165571
"orientation": 0
55175572
},
5573+
"80": {
5574+
"replace": true,
5575+
"file": "FI_080_big_dry_flower_pot.glb",
5576+
"orientation": 0
5577+
},
55185578
"81": {
55195579
"replace": true,
55205580
"file": "FI_081_francos_building_wall_window_covered.glb",
@@ -5525,6 +5585,11 @@
55255585
"file": "FI_082_francos_building_wall_window_big_covered.glb",
55265586
"orientation": 0
55275587
},
5588+
"83": {
5589+
"replace": true,
5590+
"file": "FI_083_shiny_globe.glb",
5591+
"orientation": 0
5592+
},
55285593
"84": {
55295594
"replace": true,
55305595
"file": "FI_084_dark_monk_altar.glb",

www/models/lba2/iso_scenes/115.glb

3.72 MB
Binary file not shown.

www/models/lba2/iso_scenes/116.glb

5.54 MB
Binary file not shown.

www/models/lba2/iso_scenes/117.glb

4.35 MB
Binary file not shown.

www/models/lba2/iso_scenes/118.glb

6.17 MB
Binary file not shown.

0 commit comments

Comments
 (0)