Mercurial > mm7
comparison Engine/Graphics/DecalBuilder.cpp @ 2531:f6de3e15d4a5
for light in indoor
author | Ritor1 |
---|---|
date | Sun, 23 Nov 2014 15:30:17 +0600 |
parents | 491f0babd563 |
children | 9ec6b8be16fe |
comparison
equal
deleted
inserted
replaced
2530:dc6f29bb0ec4 | 2531:f6de3e15d4a5 |
---|---|
207 } | 207 } |
208 return 1; | 208 return 1; |
209 } | 209 } |
210 | 210 |
211 //----- (0049B790) -------------------------------------------------------- | 211 //----- (0049B790) -------------------------------------------------------- |
212 char DecalBuilder::_49B790_build_decal_geometry(int a2, char a3, Bloodsplat *a4, int a5, float a6, unsigned int uColorMultiplier, float a8, stru314 *a9, signed int a10, RenderVertexSoft *a11, char uClipFlags) | 212 char DecalBuilder::_49B790_build_decal_geometry(int a2, char a3, Bloodsplat *blood, int a5, float a6, unsigned int uColorMultiplier, float a8, stru314 *a9, signed int a10, RenderVertexSoft *a11, char uClipFlags) |
213 { | 213 { |
214 Decal *v13; // edi@2 | 214 Decal *decal; // edi@2 |
215 double v28; // st7@5 | 215 double v28; // st7@5 |
216 char result; // al@6 | 216 char result; // al@6 |
217 int v34; // eax@19 | 217 int v34; // eax@19 |
218 std::string v37; // [sp-4h] [bp-24h]@15 | 218 std::string v37; // [sp-4h] [bp-24h]@15 |
219 | 219 |
220 //int a6a; | |
221 //RenderVertexSoft *a8a; | |
222 unsigned int a8b = 0; | 220 unsigned int a8b = 0; |
223 | 221 |
224 //v12 = this; | |
225 if ( a6 == 0.0 ) | 222 if ( a6 == 0.0 ) |
226 return 1; | 223 return 1; |
227 v13 = &this->std__vector_pDecals[this->field_308008]; | 224 decal = &this->std__vector_pDecals[this->field_308008]; |
228 //v14 = &this->std__vector_pDecals[this->field_308008].field_C1C; | 225 this->std__vector_pDecals[this->field_308008].field_C18 = (DecalBuilder_stru0 *)blood; |
229 this->std__vector_pDecals[this->field_308008].field_C18 = (DecalBuilder_stru0 *)a4; | |
230 this->std__vector_pDecals[this->field_308008].field_C1C = 0; | 226 this->std__vector_pDecals[this->field_308008].field_C1C = 0; |
231 if ( a3 & 2 ) | 227 if ( a3 & 2 ) |
232 this->std__vector_pDecals[this->field_308008].field_C1C = 1; | 228 this->std__vector_pDecals[this->field_308008].field_C1C = 1; |
233 //v15 = a6 - a8; | |
234 this->field_30C028 = a6 - a8; | 229 this->field_30C028 = a6 - a8; |
235 //v16 = sqrt((a6 + a6 - this->field_30C028) * this->field_30C028); | |
236 this->field_30C02C = sqrt((a6 + a6 - this->field_30C028) * this->field_30C028); | 230 this->field_30C02C = sqrt((a6 + a6 - this->field_30C028) * this->field_30C028); |
237 //v17 = a5; | 231 |
238 //v18 = a9; | |
239 this->flt_30C030 = 1.0 - (a6 - this->field_30C02C) / a6; | 232 this->flt_30C030 = 1.0 - (a6 - this->field_30C02C) / a6; |
240 v13->field_C08 = (signed __int64)(a4->x - a8 * a9->field_4.x); | 233 decal->field_C08 = (signed __int64)(blood->x - a8 * a9->field_4.x); |
241 v13->field_C0A = (signed __int64)(a4->y - a8 * a9->field_4.y); | 234 decal->field_C0A = (signed __int64)(blood->y - a8 * a9->field_4.y); |
242 //v19 = a6; | 235 decal->field_C0C = (signed __int64)(blood->z - a8 * a9->field_4.z); |
243 v13->field_C0C = (signed __int64)(a4->z - a8 * a9->field_4.z); | 236 |
244 //v20 = a6 * this->flt_30C030; | |
245 //a8a = v13->pVertices; | |
246 this->field_30C034 = a6 * this->flt_30C030; | 237 this->field_30C034 = a6 * this->flt_30C030; |
247 this->field_30C010 = this->field_30C034 * a9->field_10.x; | 238 this->field_30C010 = this->field_30C034 * a9->field_10.x; |
248 this->field_30C014 = this->field_30C034 * a9->field_10.y; | 239 this->field_30C014 = this->field_30C034 * a9->field_10.y; |
249 this->field_30C018 = this->field_30C034 * a9->field_10.z; | 240 this->field_30C018 = this->field_30C034 * a9->field_10.z; |
250 | 241 |
251 this->field_30C01C = this->field_30C034 * a9->field_1C.x; | 242 this->field_30C01C = this->field_30C034 * a9->field_1C.x; |
252 this->field_30C020 = this->field_30C034 * a9->field_1C.y; | 243 this->field_30C020 = this->field_30C034 * a9->field_1C.y; |
253 this->field_30C024 = this->field_30C034 * a9->field_1C.z; | 244 this->field_30C024 = this->field_30C034 * a9->field_1C.z; |
254 //a6a = v13->field_C08; | 245 |
255 //v21 = (double)v13->field_C08; | 246 decal->pVertices[0].vWorldPosition.x = (double)decal->field_C08 - this->field_30C01C + this->field_30C010; |
256 //v22 = (double)v13->field_C08 - this->field_30C01C; | 247 decal->pVertices[0].vWorldPosition.y = (double)decal->field_C0A - this->field_30C020 + this->field_30C014; |
257 //a6a = v13->field_C0A; | 248 decal->pVertices[0].vWorldPosition.z = (double)decal->field_C0A - this->field_30C024 + this->field_30C018; |
258 v13->pVertices[0].vWorldPosition.x = (double)v13->field_C08 - this->field_30C01C + this->field_30C010; | 249 decal->pVertices[0].u = 0.0; |
259 v13->pVertices[0].vWorldPosition.y = (double)v13->field_C0A - this->field_30C020 + this->field_30C014; | 250 decal->pVertices[0].v = 0.0; |
260 v13->pVertices[0].vWorldPosition.z = (double)v13->field_C0A - this->field_30C024 + this->field_30C018; | 251 |
261 v13->pVertices[0].u = 0.0; | 252 decal->pVertices[1].vWorldPosition.x = (double)decal->field_C08 - this->field_30C01C - this->field_30C010; |
262 v13->pVertices[0].v = 0.0; | 253 decal->pVertices[1].vWorldPosition.y = (double)decal->field_C0A - this->field_30C020 - this->field_30C014; |
263 | 254 decal->pVertices[1].vWorldPosition.z = (double)decal->field_C0A - this->field_30C024 - this->field_30C018; |
264 v13->pVertices[1].vWorldPosition.x = (double)v13->field_C08 - this->field_30C01C - this->field_30C010; | 255 decal->pVertices[1].u = 0.0; |
265 v13->pVertices[1].vWorldPosition.y = (double)v13->field_C0A - this->field_30C020 - this->field_30C014; | 256 decal->pVertices[1].v = 1.0; |
266 v13->pVertices[1].vWorldPosition.z = (double)v13->field_C0A - this->field_30C024 - this->field_30C018; | 257 |
267 v13->pVertices[1].u = 0.0; | 258 decal->pVertices[2].vWorldPosition.x = (double)decal->field_C08 + this->field_30C01C - this->field_30C010; |
268 v13->pVertices[1].v = 1.0; | 259 decal->pVertices[2].vWorldPosition.y = (double)decal->field_C0A + this->field_30C020 - this->field_30C014; |
269 | 260 decal->pVertices[2].vWorldPosition.z = (double)decal->field_C0A + this->field_30C024 - this->field_30C018; |
270 v13->pVertices[2].vWorldPosition.x = (double)v13->field_C08 + this->field_30C01C - this->field_30C010; | 261 decal->pVertices[2].u = 1.0; |
271 v13->pVertices[2].vWorldPosition.y = (double)v13->field_C0A + this->field_30C020 - this->field_30C014; | 262 decal->pVertices[2].v = 1.0; |
272 v13->pVertices[2].vWorldPosition.z = (double)v13->field_C0A + this->field_30C024 - this->field_30C018; | 263 |
273 v13->pVertices[2].u = 1.0; | 264 decal->pVertices[3].vWorldPosition.x = (double)decal->field_C08 + this->field_30C01C + this->field_30C010; |
274 v13->pVertices[2].v = 1.0; | 265 decal->pVertices[3].vWorldPosition.y = (double)decal->field_C0A + this->field_30C020 + this->field_30C014; |
275 | 266 decal->pVertices[3].vWorldPosition.z = (double)decal->field_C0A + this->field_30C024 + this->field_30C018; |
276 v13->pVertices[3].vWorldPosition.x = (double)v13->field_C08 + this->field_30C01C + this->field_30C010; | 267 decal->pVertices[3].u = 1.0; |
277 v13->pVertices[3].vWorldPosition.y = (double)v13->field_C0A + this->field_30C020 + this->field_30C014; | 268 decal->pVertices[3].v = 0.0; |
278 v13->pVertices[3].vWorldPosition.z = (double)v13->field_C0A + this->field_30C024 + this->field_30C018; | |
279 v13->pVertices[3].u = 1.0; | |
280 v13->pVertices[3].v = 0.0; | |
281 | 269 |
282 for ( uint i = 0; i < 4; ++i ) | 270 for ( uint i = 0; i < 4; ++i ) |
283 { | 271 { |
284 v28 = a9->field_4.x * v13->pVertices[i].vWorldPosition.x | 272 v28 = a9->field_4.x * decal->pVertices[i].vWorldPosition.x |
285 + a9->field_4.y * v13->pVertices[i].vWorldPosition.y | 273 + a9->field_4.y * decal->pVertices[i].vWorldPosition.y |
286 + a9->field_4.z * v13->pVertices[i].vWorldPosition.z | 274 + a9->field_4.z * decal->pVertices[i].vWorldPosition.z |
287 + a9->dist; | 275 + a9->dist; |
288 v13->pVertices[i].vWorldPosition.x = v13->pVertices[i].vWorldPosition.x - v28 * a9->field_4.x; | 276 decal->pVertices[i].vWorldPosition.x = decal->pVertices[i].vWorldPosition.x - v28 * a9->field_4.x; |
289 v13->pVertices[i].vWorldPosition.y = v13->pVertices[i].vWorldPosition.y - v28 * a9->field_4.y; | 277 decal->pVertices[i].vWorldPosition.y = decal->pVertices[i].vWorldPosition.y - v28 * a9->field_4.y; |
290 v13->pVertices[i].vWorldPosition.z = v13->pVertices[i].vWorldPosition.z - v28 * a9->field_4.z; | 278 decal->pVertices[i].vWorldPosition.z = decal->pVertices[i].vWorldPosition.z - v28 * a9->field_4.z; |
291 //v25 += 48; | 279 } |
292 } | 280 decal->uColorMultiplier = uColorMultiplier; |
293 v13->uColorMultiplier = uColorMultiplier; | 281 decal->uNumVertices = 4; |
294 //v40 = (unsigned int *)&v13->uNumVertices; | 282 decal->field_C14 = a2; |
295 //v39 = v13->pVertices; | 283 result = pGame->pStru9Instance->_4980B9(a11, a10, a9->field_4.x, a9->field_4.y, a9->field_4.z, decal->pVertices, (unsigned int*)&decal->uNumVertices); |
296 v13->uNumVertices = 4; | |
297 v13->field_C14 = a2; | |
298 //v29 = a9->field_4.z; | |
299 //a6a = (unsigned int *)&v13->uNumVertices; | |
300 //v38 = a9->field_4.z; | |
301 result = pGame->pStru9Instance->_4980B9(a11, a10, a9->field_4.x, a9->field_4.y, a9->field_4.z, v13->pVertices, (unsigned int*)&v13->uNumVertices); | |
302 if ( result ) | 284 if ( result ) |
303 { | 285 { |
304 //v31 = a6a; | 286 if ( !decal->uNumVertices ) |
305 if ( !v13->uNumVertices ) | |
306 return 1; | 287 return 1; |
307 //v32 = a8a; | 288 |
308 //v40 = *a6a; | 289 pGame->pIndoorCameraD3D->ViewTransform(decal->pVertices, (unsigned int)decal->uNumVertices); |
309 //v39 = a8a; | 290 pGame->pIndoorCameraD3D->Project(decal->pVertices, decal->uNumVertices, 0); |
310 pGame->pIndoorCameraD3D->ViewTransform(v13->pVertices, (unsigned int)v13->uNumVertices); | |
311 //v40 = 0; | |
312 pGame->pIndoorCameraD3D->Project(v13->pVertices, v13->uNumVertices, 0); | |
313 if ( !(uClipFlags & 1) ) | 291 if ( !(uClipFlags & 1) ) |
314 { | 292 { |
315 ++this->field_308008; | 293 ++this->field_308008; |
316 v34 = 1024; | 294 v34 = 1024; |
317 if ( this->field_308008 == 1024 ) | 295 if ( this->field_308008 == 1024 ) |
323 } | 301 } |
324 if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) | 302 if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) |
325 { | 303 { |
326 if ( uClipFlags & 2 ) | 304 if ( uClipFlags & 2 ) |
327 { | 305 { |
328 //v40 = (int)&a8; | 306 pGame->pIndoorCameraD3D->_436CDC_mess_with_lightmap__clipflag_2(decal->pVertices, decal->uNumVertices, this->pVertices, &a8b); |
329 //v39 = this->pVertices; | 307 pGame->pIndoorCameraD3D->_437143(a8b, decal->pVertices, this->pVertices, (unsigned int *)&decal->uNumVertices); |
330 //__debugbreak(); // warning C4700: uninitialized local variable 'v31' used | |
331 pGame->pIndoorCameraD3D->_436CDC_mess_with_lightmap__clipflag_2(v13->pVertices, v13->uNumVertices, this->pVertices, &a8b); | |
332 //v40 = (int)v31; | |
333 //v39 = this->pVertices; | |
334 pGame->pIndoorCameraD3D->_437143(a8b, v13->pVertices, this->pVertices, (unsigned int *)&v13->uNumVertices); | |
335 } | 308 } |
336 else if ( uClipFlags & 4 ) | 309 else if ( uClipFlags & 4 ) |
337 { | 310 { |
338 //v40 = (int)&a8; | 311 pGame->pIndoorCameraD3D->_436F09_mess_with_lightmap__clipflag_4(decal->pVertices, decal->uNumVertices, this->pVertices, &a8b); |
339 //v39 = this->pVertices; | 312 pGame->pIndoorCameraD3D->_437143(a8b, decal->pVertices, this->pVertices, (unsigned int *)&decal->uNumVertices); |
340 pGame->pIndoorCameraD3D->_436F09_mess_with_lightmap__clipflag_4(v13->pVertices, v13->uNumVertices, this->pVertices, &a8b); | |
341 //v40 = (int)v31; | |
342 //v39 = this->pVertices; | |
343 pGame->pIndoorCameraD3D->_437143(a8b, v13->pVertices, this->pVertices, (unsigned int *)&v13->uNumVertices); | |
344 } | 313 } |
345 else | 314 else |
346 MessageBoxA(nullptr, "Undefined clip flag specified", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:258", 0); | 315 MessageBoxA(nullptr, "Undefined clip flag specified", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:258", 0); |
347 } | 316 } |
348 else | 317 else |
464 // int v27; // [sp+24h] [bp-18h]@12 | 433 // int v27; // [sp+24h] [bp-18h]@12 |
465 float v28; // [sp+28h] [bp-14h]@13 | 434 float v28; // [sp+28h] [bp-14h]@13 |
466 //float v29; // [sp+2Ch] [bp-10h]@7 | 435 //float v29; // [sp+2Ch] [bp-10h]@7 |
467 float v30; // [sp+30h] [bp-Ch]@6 | 436 float v30; // [sp+30h] [bp-Ch]@6 |
468 float v31; // [sp+34h] [bp-8h]@6 | 437 float v31; // [sp+34h] [bp-8h]@6 |
469 bool v32; // [sp+38h] [bp-4h]@2 | 438 //bool v32; // [sp+38h] [bp-4h]@2 |
470 float a3; | 439 float a3; |
471 | 440 |
472 this->uNumDecals = 0; | 441 this->uNumDecals = 0; |
473 result = pBloodsplatContainer->std__vector_pBloodsplats_size != 0; | 442 if ( !pBloodsplatContainer->std__vector_pBloodsplats_size ) |
443 return false; | |
474 // v24 = this; | 444 // v24 = this; |
475 v23 = pBloodsplatContainer->std__vector_pBloodsplats_size; | 445 v23 = pBloodsplatContainer->std__vector_pBloodsplats_size; |
476 if ( pBloodsplatContainer->std__vector_pBloodsplats_size ) | 446 if ( pBloodsplatContainer->std__vector_pBloodsplats_size ) |
477 { | 447 { |
478 | 448 |
479 if ( (signed int)pBloodsplatContainer->std__vector_pBloodsplats_size > 0 ) | 449 if ( (signed int)pBloodsplatContainer->std__vector_pBloodsplats_size > 0 ) |
480 { | 450 { |
481 //v8 = a5; | 451 //v8 = a5; |
482 //v9 = _a3; | 452 //v9 = _a3; |
483 for ( v32 = 0; v32 < (signed int)v23; ++v32 ) | 453 for ( uint i = 0; i < (signed int)v23; ++i ) |
484 { | 454 { |
485 if ( uStripType == 4 ) | 455 if ( uStripType == 4 ) |
486 { | 456 { |
487 a3 = a5->vWorldPosition.x; | 457 a3 = a5->vWorldPosition.x; |
488 //v11 = v8[3].vWorldPosition.x; | 458 //v11 = v8[3].vWorldPosition.x; |
516 //v21 = uStripType; | 486 //v21 = uStripType; |
517 //v13 = pGame->pIndoorCameraD3D->GetPolygonMinZ(v8, uStripType); | 487 //v13 = pGame->pIndoorCameraD3D->GetPolygonMinZ(v8, uStripType); |
518 //v21 = uStripType; | 488 //v21 = uStripType; |
519 v28 = pGame->pIndoorCameraD3D->GetPolygonMinZ(a5, uStripType); | 489 v28 = pGame->pIndoorCameraD3D->GetPolygonMinZ(a5, uStripType); |
520 v26 = pGame->pIndoorCameraD3D->GetPolygonMaxZ(a5, uStripType); | 490 v26 = pGame->pIndoorCameraD3D->GetPolygonMaxZ(a5, uStripType); |
521 if ( a3 - pBloodsplatContainer->std__vector_pBloodsplats[v32].radius < pBloodsplatContainer->std__vector_pBloodsplats[v32].x && | 491 if ( a3 - pBloodsplatContainer->std__vector_pBloodsplats[i].radius < pBloodsplatContainer->std__vector_pBloodsplats[i].x && |
522 v31 + pBloodsplatContainer->std__vector_pBloodsplats[v32].radius > pBloodsplatContainer->std__vector_pBloodsplats[v32].x && | 492 v31 + pBloodsplatContainer->std__vector_pBloodsplats[i].radius > pBloodsplatContainer->std__vector_pBloodsplats[i].x && |
523 v30 - pBloodsplatContainer->std__vector_pBloodsplats[v32].radius < pBloodsplatContainer->std__vector_pBloodsplats[v32].y && | 493 v30 - pBloodsplatContainer->std__vector_pBloodsplats[i].radius < pBloodsplatContainer->std__vector_pBloodsplats[i].y && |
524 v12 + pBloodsplatContainer->std__vector_pBloodsplats[v32].radius > pBloodsplatContainer->std__vector_pBloodsplats[v32].y && | 494 v12 + pBloodsplatContainer->std__vector_pBloodsplats[i].radius > pBloodsplatContainer->std__vector_pBloodsplats[i].y && |
525 v28 - pBloodsplatContainer->std__vector_pBloodsplats[v32].radius < pBloodsplatContainer->std__vector_pBloodsplats[v32].z && | 495 v28 - pBloodsplatContainer->std__vector_pBloodsplats[i].radius < pBloodsplatContainer->std__vector_pBloodsplats[i].z && |
526 v26 + pBloodsplatContainer->std__vector_pBloodsplats[v32].radius > pBloodsplatContainer->std__vector_pBloodsplats[v32].z ) | 496 v26 + pBloodsplatContainer->std__vector_pBloodsplats[i].radius > pBloodsplatContainer->std__vector_pBloodsplats[i].z ) |
527 { | 497 { |
528 Vec3_float_::NegDot(&a5->vWorldPosition, _a3, a4); | 498 Vec3_float_::NegDot(&a5->vWorldPosition, _a3, a4); |
529 v26 = _a3->y * pBloodsplatContainer->std__vector_pBloodsplats[v32].y | 499 v26 = _a3->y * pBloodsplatContainer->std__vector_pBloodsplats[i].y |
530 + _a3->z * pBloodsplatContainer->std__vector_pBloodsplats[v32].z | 500 + _a3->z * pBloodsplatContainer->std__vector_pBloodsplats[i].z |
531 + _a3->x * pBloodsplatContainer->std__vector_pBloodsplats[v32].x | 501 + _a3->x * pBloodsplatContainer->std__vector_pBloodsplats[i].x |
532 + *a4; | 502 + *a4; |
533 v22 = v26 + 6.7553994e15; | 503 v22 = v26 + 0.5f; |
534 //v25 = LODWORD(v22); | 504 //v25 = LODWORD(v22); |
535 v14 = (double)SLODWORD(v22); | 505 v14 = (double)SLODWORD(v22); |
536 v28 = v14; | 506 v28 = v14; |
537 if ( v14 <= pBloodsplatContainer->std__vector_pBloodsplats[v32].radius ) | 507 if ( v14 <= pBloodsplatContainer->std__vector_pBloodsplats[i].radius ) |
538 { | 508 { |
539 //v15 = a2->flags; | 509 //v15 = a2->flags; |
540 if ( a2->flags & 2 || a2->flags & 0x100 ) | 510 if ( a2->flags & 2 || a2->flags & 0x100 ) |
541 { | 511 { |
542 v16 = pBloodsplatContainer->std__vector_pBloodsplats[v32].field_1C; | 512 v16 = pBloodsplatContainer->std__vector_pBloodsplats[i].field_1C; |
543 if ( !(pBloodsplatContainer->std__vector_pBloodsplats[v32].field_1C & 1) ) | 513 if ( !(pBloodsplatContainer->std__vector_pBloodsplats[i].field_1C & 1) ) |
544 { | 514 { |
545 LOBYTE(v16) = v16 | 1; | 515 LOBYTE(v16) = v16 | 1; |
546 pBloodsplatContainer->std__vector_pBloodsplats[v32].field_1C = v16; | 516 pBloodsplatContainer->std__vector_pBloodsplats[i].field_1C = v16; |
547 pBloodsplatContainer->std__vector_pBloodsplats[v32].field_20 = pEventTimer->Time(); | 517 pBloodsplatContainer->std__vector_pBloodsplats[i].field_20 = pEventTimer->Time(); |
548 } | 518 } |
549 } | 519 } |
550 //v17 = v32; | 520 //v17 = v32; |
551 pBloodsplatContainer->std__vector_pBloodsplats[v32].dot_dist = LODWORD(v28); | 521 pBloodsplatContainer->std__vector_pBloodsplats[i].dot_dist = LODWORD(v28); |
552 //v18 = this; | 522 //v18 = this; |
553 this->std__vector_30B00C[this->uNumDecals] = v32; | 523 this->std__vector_30B00C[this->uNumDecals] = i; |
554 ++this->uNumDecals; | 524 ++this->uNumDecals; |
555 } | 525 } |
556 } | 526 } |
557 //++v32; | 527 //++v32; |
558 //++v10; | 528 //++v10; |
559 result = v32; | 529 result = i; |
560 } | 530 } |
561 } | 531 } |
562 } | 532 } |
563 LOBYTE(result) = 1; | 533 //LOBYTE(result) = 1; |
564 return result; | 534 return true; |
565 } | 535 } |
566 | 536 |
567 | 537 |
568 //----- (0049C2CD) -------------------------------------------------------- | 538 //----- (0049C2CD) -------------------------------------------------------- |
569 void DecalBuilder::DrawDecals(float z_bias) | 539 void DecalBuilder::DrawDecals(float z_bias) |