@@ -272,6 +272,25 @@ void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
272
272
}
273
273
}
274
274
275
+ // Calculates screen position of waypoint. Returns true if waypoint is visible (in front of the player), else false.
276
+ bool Hud::calculateScreenPos (const v3s16 &camera_offset, HudElement *e, v2s32 *pos)
277
+ {
278
+ v3f w_pos = e->world_pos * BS;
279
+ scene::ICameraSceneNode* camera =
280
+ RenderingEngine::get_scene_manager ()->getActiveCamera ();
281
+ w_pos -= intToFloat (camera_offset, BS);
282
+ core::matrix4 trans = camera->getProjectionMatrix ();
283
+ trans *= camera->getViewMatrix ();
284
+ f32 transformed_pos[4 ] = { w_pos.X , w_pos.Y , w_pos.Z , 1 .0f };
285
+ trans.multiplyWith1x4Matrix (transformed_pos);
286
+ if (transformed_pos[3 ] < 0 )
287
+ return false ;
288
+ f32 zDiv = transformed_pos[3 ] == 0 .0f ? 1 .0f :
289
+ core::reciprocal (transformed_pos[3 ]);
290
+ pos->X = m_screensize.X * (0.5 * transformed_pos[0 ] * zDiv + 0.5 );
291
+ pos->Y = m_screensize.Y * (0.5 - transformed_pos[1 ] * zDiv * 0.5 );
292
+ return true ;
293
+ }
275
294
276
295
void Hud::drawLuaElements (const v3s16 &camera_offset)
277
296
{
@@ -299,28 +318,6 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
299
318
v2s32 pos (floor (e->pos .X * (float ) m_screensize.X + 0.5 ),
300
319
floor (e->pos .Y * (float ) m_screensize.Y + 0.5 ));
301
320
switch (e->type ) {
302
- case HUD_ELEM_IMAGE: {
303
- video::ITexture *texture = tsrc->getTexture (e->text );
304
- if (!texture)
305
- continue ;
306
-
307
- const video::SColor color (255 , 255 , 255 , 255 );
308
- const video::SColor colors[] = {color, color, color, color};
309
- core::dimension2di imgsize (texture->getOriginalSize ());
310
- v2s32 dstsize (imgsize.Width * e->scale .X ,
311
- imgsize.Height * e->scale .Y );
312
- if (e->scale .X < 0 )
313
- dstsize.X = m_screensize.X * (e->scale .X * -0.01 );
314
- if (e->scale .Y < 0 )
315
- dstsize.Y = m_screensize.Y * (e->scale .Y * -0.01 );
316
- v2s32 offset ((e->align .X - 1.0 ) * dstsize.X / 2 ,
317
- (e->align .Y - 1.0 ) * dstsize.Y / 2 );
318
- core::rect<s32> rect (0 , 0 , dstsize.X , dstsize.Y );
319
- rect += pos + offset + v2s32 (e->offset .X , e->offset .Y );
320
- draw2DImageFilterScaled (driver, texture, rect,
321
- core::rect<s32>(core::position2d<s32>(0 ,0 ), imgsize),
322
- NULL , colors, true );
323
- break ; }
324
321
case HUD_ELEM_TEXT: {
325
322
video::SColor color (255 , (e->number >> 16 ) & 0xFF ,
326
323
(e->number >> 8 ) & 0xFF ,
@@ -343,34 +340,58 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
343
340
inv, e->item , e->dir );
344
341
break ; }
345
342
case HUD_ELEM_WAYPOINT: {
346
- v3f p_pos = player->getPosition () / BS;
347
- v3f w_pos = e->world_pos * BS;
348
- float distance = std::floor (10 * p_pos.getDistanceFrom (e->world_pos )) /
349
- 10 .0f ;
350
- scene::ICameraSceneNode* camera =
351
- RenderingEngine::get_scene_manager ()->getActiveCamera ();
352
- w_pos -= intToFloat (camera_offset, BS);
353
- core::matrix4 trans = camera->getProjectionMatrix ();
354
- trans *= camera->getViewMatrix ();
355
- f32 transformed_pos[4 ] = { w_pos.X , w_pos.Y , w_pos.Z , 1 .0f };
356
- trans.multiplyWith1x4Matrix (transformed_pos);
357
- if (transformed_pos[3 ] < 0 )
343
+ if (!calculateScreenPos (camera_offset, e, &pos))
358
344
break ;
359
- f32 zDiv = transformed_pos[3 ] == 0 .0f ? 1 .0f :
360
- core::reciprocal (transformed_pos[3 ]);
361
- pos.X = m_screensize.X * (0.5 * transformed_pos[0 ] * zDiv + 0.5 );
362
- pos.Y = m_screensize.Y * (0.5 - transformed_pos[1 ] * zDiv * 0.5 );
345
+ v3f p_pos = player->getPosition () / BS;
346
+ pos += v2s32 (e->offset .X , e->offset .Y );
363
347
video::SColor color (255 , (e->number >> 16 ) & 0xFF ,
364
348
(e->number >> 8 ) & 0xFF ,
365
349
(e->number >> 0 ) & 0xFF );
366
- core::rect<s32> size (0 , 0 , 200 , 2 * text_height);
367
350
std::wstring text = unescape_translate (utf8_to_wide (e->name ));
368
- font->draw (text.c_str (), size + pos, color);
369
- std::ostringstream os;
370
- os << distance << e->text ;
371
- text = unescape_translate (utf8_to_wide (os.str ()));
372
- pos.Y += text_height;
373
- font->draw (text.c_str (), size + pos, color);
351
+ const std::string &unit = e->text ;
352
+ // waypoints reuse the item field to store precision, item = precision + 1
353
+ u32 item = e->item ;
354
+ float precision = (item == 0 ) ? 10 .0f : (item - 1 .f );
355
+ bool draw_precision = precision > 0 ;
356
+
357
+ core::rect<s32> bounds (0 , 0 , font->getDimension (text.c_str ()).Width , (draw_precision ? 2 :1 ) * text_height);
358
+ pos.Y += (e->align .Y - 1.0 ) * bounds.getHeight () / 2 ;
359
+ bounds += pos;
360
+ font->draw (text.c_str (), bounds + v2s32 ((e->align .X - 1.0 ) * bounds.getWidth () / 2 , 0 ), color);
361
+ if (draw_precision) {
362
+ std::ostringstream os;
363
+ float distance = std::floor (precision * p_pos.getDistanceFrom (e->world_pos )) / precision;
364
+ os << distance << unit;
365
+ text = unescape_translate (utf8_to_wide (os.str ()));
366
+ bounds.LowerRightCorner .X = bounds.UpperLeftCorner .X + font->getDimension (text.c_str ()).Width ;
367
+ font->draw (text.c_str (), bounds + v2s32 ((e->align .X - 1 .0f ) * bounds.getWidth () / 2 , text_height), color);
368
+ }
369
+ break ; }
370
+ case HUD_ELEM_IMAGE_WAYPOINT: {
371
+ if (!calculateScreenPos (camera_offset, e, &pos))
372
+ break ;
373
+ }
374
+ case HUD_ELEM_IMAGE: {
375
+ video::ITexture *texture = tsrc->getTexture (e->text );
376
+ if (!texture)
377
+ continue ;
378
+
379
+ const video::SColor color (255 , 255 , 255 , 255 );
380
+ const video::SColor colors[] = {color, color, color, color};
381
+ core::dimension2di imgsize (texture->getOriginalSize ());
382
+ v2s32 dstsize (imgsize.Width * e->scale .X ,
383
+ imgsize.Height * e->scale .Y );
384
+ if (e->scale .X < 0 )
385
+ dstsize.X = m_screensize.X * (e->scale .X * -0.01 );
386
+ if (e->scale .Y < 0 )
387
+ dstsize.Y = m_screensize.Y * (e->scale .Y * -0.01 );
388
+ v2s32 offset ((e->align .X - 1.0 ) * dstsize.X / 2 ,
389
+ (e->align .Y - 1.0 ) * dstsize.Y / 2 );
390
+ core::rect<s32> rect (0 , 0 , dstsize.X , dstsize.Y );
391
+ rect += pos + offset + v2s32 (e->offset .X , e->offset .Y );
392
+ draw2DImageFilterScaled (driver, texture, rect,
393
+ core::rect<s32>(core::position2d<s32>(0 ,0 ), imgsize),
394
+ NULL , colors, true );
374
395
break ; }
375
396
default :
376
397
infostream << " Hud::drawLuaElements: ignoring drawform " << e->type <<
0 commit comments