@@ -45,7 +45,7 @@ export class Viewer {
45
45
this . camera . position . set ( 0 , 0 , 5 ) ;
46
46
this . controls = new OrbitControls ( this . camera , this . renderer . domElement ) ;
47
47
this . controls . enablePan = true ;
48
- this . setControlsRotation ( Math . PI / 3 , Math . PI / 4 ) ;
48
+ // this.setControlsRotation(Math.PI / 3, Math.PI / 4);
49
49
// TODO: This does not work properly.
50
50
const resizeObserver = new ResizeObserver ( ( ) => {
51
51
const width = 0.9 * this . container . clientWidth ;
@@ -64,14 +64,114 @@ export class Viewer {
64
64
light . position . set ( 10 , 10 , - 10 ) . normalize ( ) ;
65
65
this . scene . add ( light ) ;
66
66
67
- // Add a test cube.
68
- const length = 4 ;
69
- const width = 2 ;
70
- const depth = 2 ;
71
- const geometry = new THREE . BoxGeometry ( length , width , depth ) ;
72
- const material = new THREE . MeshPhongMaterial ( { color : 0x888888 } ) ;
73
- const cube = new THREE . Mesh ( geometry , material ) ;
74
- this . scene . add ( cube ) ;
67
+ const vertices : number [ ] = [ ] ;
68
+ const values : number [ ] = [ ] ;
69
+ const N_FIXED = 4 ;
70
+ const H = 0.6 ;
71
+ const L = 2 * H ;
72
+ const dr = H / 80.0 ;
73
+ const POOL_WIDTH = 5.366 * H ;
74
+ const POOL_HEIGHT = 2.5 * H ;
75
+ const POOL_M = Math . round ( POOL_WIDTH / dr ) ;
76
+ const POOL_N = Math . round ( POOL_HEIGHT / dr ) ;
77
+ const WATER_M = Math . round ( L / dr ) ;
78
+ const WATER_N = Math . round ( H / dr ) ;
79
+ const g = 9.81 ;
80
+ const rho_0 = 1000 ;
81
+ for ( let i = - N_FIXED ; i < POOL_M + N_FIXED ; ++ i ) {
82
+ for ( let j = - N_FIXED ; j < POOL_N ; ++ j ) {
83
+ const is_fixed = i < 0 || i >= POOL_M || j < 0 ;
84
+ const is_fluid = i < WATER_M && j < WATER_N ;
85
+
86
+ if ( ! is_fixed && ! is_fluid ) continue ;
87
+
88
+ vertices . push ( dr * ( i + 0.5 ) , dr * ( j + 0.5 ) , 0 ) ;
89
+ values . push ( 0 ) ;
90
+ }
91
+ }
92
+ for ( let i = 0 ; i < vertices . length / 3 ; i ++ ) {
93
+ const x = vertices [ i * 3 ] ;
94
+ const y = vertices [ i * 3 + 1 ] ;
95
+ if ( x < 0 || x >= L || y < 0 || y >= H ) continue ;
96
+
97
+ let pressure = rho_0 * g * ( H - y ) ;
98
+ for ( let n = 1 ; n < 2 ; n += 2 ) {
99
+ const pi = Math . PI ;
100
+ pressure -=
101
+ ( ( ( 8 * rho_0 * g * H ) / ( pi * pi ) ) *
102
+ ( Math . exp ( ( n * pi * ( x - L ) ) / ( 2 * H ) ) *
103
+ Math . cos ( ( n * pi * y ) / ( 2 * H ) ) ) ) /
104
+ ( n * n ) ;
105
+ }
106
+ values [ i ] = pressure ;
107
+ }
108
+ let minValue = Infinity ;
109
+ let maxValue = - Infinity ;
110
+ for ( let i = 0 ; i < values . length ; i ++ ) {
111
+ minValue = Math . min ( minValue , values [ i ] ) ;
112
+ maxValue = Math . max ( maxValue , values [ i ] ) ;
113
+ }
114
+ const range = maxValue - minValue ;
115
+ for ( let i = 0 ; i < values . length ; i ++ ) {
116
+ values [ i ] = ( values [ i ] - minValue ) / range ;
117
+ vertices [ i * 3 ] -= POOL_WIDTH / 2 ;
118
+ vertices [ i * 3 + 1 ] -= POOL_HEIGHT / 2 ;
119
+ }
120
+
121
+ const geometry = new THREE . BufferGeometry ( ) ;
122
+ geometry . setAttribute (
123
+ "position" ,
124
+ new THREE . Float32BufferAttribute ( vertices , 3 )
125
+ ) ;
126
+ geometry . setAttribute ( "value" , new THREE . Float32BufferAttribute ( values , 1 ) ) ;
127
+ const material = new THREE . ShaderMaterial ( {
128
+ uniforms : {
129
+ pointSize : { value : 0.0075 } ,
130
+ cameraNear : { value : this . camera . near } ,
131
+ cameraFar : { value : this . camera . far } ,
132
+ lightPosition : { value : new THREE . Vector3 ( 10 , 10 , - 10 ) } ,
133
+ ambientLightColor : { value : new THREE . Color ( 0xaaaaaa ) } ,
134
+ pointLightColor : { value : new THREE . Color ( 0xffffff ) } ,
135
+ } ,
136
+ vertexShader : `
137
+ uniform float pointSize;
138
+ uniform float cameraNear;
139
+ uniform float cameraFar;
140
+ uniform vec3 lightPosition;
141
+ in float value;
142
+ out float fragValue;
143
+ void main() {
144
+ vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
145
+ gl_PointSize = pointSize * (cameraFar - cameraNear) / length(mvPosition.xyz);
146
+ gl_Position = projectionMatrix * mvPosition;
147
+ fragValue = value;
148
+ }
149
+ ` ,
150
+ fragmentShader : `
151
+ in float fragValue;
152
+ uniform vec3 lightPosition;
153
+ uniform vec3 ambientLightColor;
154
+ uniform vec3 pointLightColor;
155
+ vec3 jetColormap(float t) {
156
+ t = clamp(t, 0.0, 1.0);
157
+ float r = smoothstep(0.375, 0.625, t) + smoothstep(0.75, 1.0, t);
158
+ float g = smoothstep(0.0, 0.5, t) - smoothstep(0.75, 1.0, t);
159
+ float b = smoothstep(0.0, 0.25, t) - smoothstep(0.5, 0.75, t);
160
+ return vec3(r, g, b);
161
+ }
162
+ void main() {
163
+ vec2 pos = gl_PointCoord.xy - vec2(0.5);
164
+ vec3 normal = normalize(vec3(pos, sqrt(1.0 - dot(pos, pos))));
165
+ if (length(pos) > 0.5) discard;
166
+ vec3 lightDirection = normalize(lightPosition - vec3(gl_FragCoord));
167
+ float lightIntensity = max(dot(lightDirection, normal), 0.0);
168
+ vec3 color = ambientLightColor + pointLightColor * lightIntensity;
169
+ gl_FragColor = vec4(color * jetColormap(fragValue), 1.0);
170
+ }
171
+ ` ,
172
+ } ) ;
173
+ const particles = new THREE . Points ( geometry , material ) ;
174
+ this . scene . add ( particles ) ;
75
175
}
76
176
77
177
setControlsRotation ( polar : number , azimuthal : number ) {
0 commit comments