@@ -240,50 +240,63 @@ void WieldMeshSceneNode::setCube(const ContentFeatures &f,
240
240
}
241
241
242
242
void WieldMeshSceneNode::setExtruded (const std::string &imagename,
243
- v3f wield_scale, ITextureSource *tsrc, u8 num_frames)
243
+ const std::string &overlay_name, v3f wield_scale, ITextureSource *tsrc,
244
+ u8 num_frames)
244
245
{
245
246
video::ITexture *texture = tsrc->getTexture (imagename);
246
247
if (!texture) {
247
248
changeToMesh (nullptr );
248
249
return ;
249
250
}
251
+ video::ITexture *overlay_texture =
252
+ overlay_name.empty () ? NULL : tsrc->getTexture (overlay_name);
250
253
251
254
core::dimension2d<u32 > dim = texture->getSize ();
252
255
// Detect animation texture and pull off top frame instead of using entire thing
253
256
if (num_frames > 1 ) {
254
257
u32 frame_height = dim.Height / num_frames;
255
258
dim = core::dimension2d<u32 >(dim.Width , frame_height);
256
259
}
257
- scene::IMesh *mesh = g_extrusion_mesh_cache->create (dim);
258
- scene::SMesh *copy = cloneMesh (mesh);
260
+ scene::IMesh *original = g_extrusion_mesh_cache->create (dim);
261
+ scene::SMesh *mesh = cloneMesh (original);
262
+ original->drop ();
263
+ // set texture
264
+ mesh->getMeshBuffer (0 )->getMaterial ().setTexture (0 ,
265
+ tsrc->getTexture (imagename));
266
+ if (overlay_texture) {
267
+ scene::IMeshBuffer *copy = cloneMeshBuffer (mesh->getMeshBuffer (0 ));
268
+ copy->getMaterial ().setTexture (0 , overlay_texture);
269
+ mesh->addMeshBuffer (copy);
270
+ copy->drop ();
271
+ }
272
+ changeToMesh (mesh);
259
273
mesh->drop ();
260
- changeToMesh (copy);
261
- copy->drop ();
262
274
263
275
m_meshnode->setScale (wield_scale * WIELD_SCALE_FACTOR_EXTRUDED);
264
276
265
- // Customize material
266
- video::SMaterial &material = m_meshnode->getMaterial ( 0 );
267
- material. setTexture ( 0 , tsrc-> getTextureForMesh (imagename) );
268
- material.TextureLayer [0 ].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
269
- material.TextureLayer [0 ].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
270
- material.MaterialType = m_material_type;
271
- material.setFlag (video::EMF_BACK_FACE_CULLING, true );
272
- // Enable bi/trilinear filtering only for high resolution textures
273
- if (dim.Width > 32 ) {
274
- material.setFlag (video::EMF_BILINEAR_FILTER, m_bilinear_filter);
275
- material.setFlag (video::EMF_TRILINEAR_FILTER, m_trilinear_filter);
276
- } else {
277
- material.setFlag (video::EMF_BILINEAR_FILTER, false );
278
- material.setFlag (video::EMF_TRILINEAR_FILTER, false );
279
- }
280
- material.setFlag (video::EMF_ANISOTROPIC_FILTER, m_anisotropic_filter);
281
- // mipmaps cause "thin black line" artifacts
277
+ // Customize materials
278
+ for ( u32 layer = 0 ; layer < m_meshnode->getMaterialCount (); layer++) {
279
+ video::SMaterial & material = m_meshnode-> getMaterial (layer );
280
+ material.TextureLayer [0 ].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
281
+ material.TextureLayer [0 ].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
282
+ material.MaterialType = m_material_type;
283
+ material.setFlag (video::EMF_BACK_FACE_CULLING, true );
284
+ // Enable bi/trilinear filtering only for high resolution textures
285
+ if (dim.Width > 32 ) {
286
+ material.setFlag (video::EMF_BILINEAR_FILTER, m_bilinear_filter);
287
+ material.setFlag (video::EMF_TRILINEAR_FILTER, m_trilinear_filter);
288
+ } else {
289
+ material.setFlag (video::EMF_BILINEAR_FILTER, false );
290
+ material.setFlag (video::EMF_TRILINEAR_FILTER, false );
291
+ }
292
+ material.setFlag (video::EMF_ANISOTROPIC_FILTER, m_anisotropic_filter);
293
+ // mipmaps cause "thin black line" artifacts
282
294
#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
283
- material.setFlag (video::EMF_USE_MIP_MAPS, false );
295
+ material.setFlag (video::EMF_USE_MIP_MAPS, false );
284
296
#endif
285
- if (m_enable_shaders) {
286
- material.setTexture (2 , tsrc->getShaderFlagsTexture (false ));
297
+ if (m_enable_shaders) {
298
+ material.setTexture (2 , tsrc->getShaderFlagsTexture (false ));
299
+ }
287
300
}
288
301
}
289
302
@@ -308,8 +321,11 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client)
308
321
309
322
// If wield_image is defined, it overrides everything else
310
323
if (!def.wield_image .empty ()) {
311
- setExtruded (def.wield_image , def.wield_scale , tsrc, 1 );
324
+ setExtruded (def.wield_image , def.wield_overlay , def.wield_scale , tsrc,
325
+ 1 );
312
326
m_colors.emplace_back ();
327
+ // overlay is white, if present
328
+ m_colors.emplace_back (true , video::SColor (0xFFFFFFFF ));
313
329
return ;
314
330
}
315
331
@@ -335,14 +351,23 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client)
335
351
}
336
352
case NDT_PLANTLIKE: {
337
353
setExtruded (tsrc->getTextureName (f.tiles [0 ].layers [0 ].texture_id ),
354
+ tsrc->getTextureName (f.tiles [0 ].layers [1 ].texture_id ),
338
355
def.wield_scale , tsrc,
339
356
f.tiles [0 ].layers [0 ].animation_frame_count );
357
+ // Add color
358
+ const TileLayer &l0 = f.tiles [0 ].layers [0 ];
359
+ m_colors.emplace_back (l0.has_color , l0.color );
360
+ const TileLayer &l1 = f.tiles [0 ].layers [1 ];
361
+ m_colors.emplace_back (l1.has_color , l1.color );
340
362
break ;
341
363
}
342
364
case NDT_PLANTLIKE_ROOTED: {
343
365
setExtruded (tsrc->getTextureName (f.special_tiles [0 ].layers [0 ].texture_id ),
344
- def.wield_scale , tsrc,
366
+ " " , def.wield_scale , tsrc,
345
367
f.special_tiles [0 ].layers [0 ].animation_frame_count );
368
+ // Add color
369
+ const TileLayer &l0 = f.special_tiles [0 ].layers [0 ];
370
+ m_colors.emplace_back (l0.has_color , l0.color );
346
371
break ;
347
372
}
348
373
case NDT_NORMAL:
@@ -376,10 +401,12 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client)
376
401
}
377
402
return ;
378
403
}
379
-
380
- if (! def.inventory_image . empty ()) {
381
- setExtruded (def. inventory_image , def. wield_scale , tsrc, 1 );
404
+ else if (!def. inventory_image . empty ()) {
405
+ setExtruded ( def.inventory_image , def. inventory_overlay , def. wield_scale ,
406
+ tsrc, 1 );
382
407
m_colors.emplace_back ();
408
+ // overlay is white, if present
409
+ m_colors.emplace_back (true , video::SColor (0xFFFFFFFF ));
383
410
return ;
384
411
}
385
412
@@ -456,24 +483,38 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
456
483
457
484
// If inventory_image is defined, it overrides everything else
458
485
if (!def.inventory_image .empty ()) {
459
- mesh = getExtrudedMesh (tsrc, def.inventory_image );
486
+ mesh = getExtrudedMesh (tsrc, def.inventory_image ,
487
+ def.inventory_overlay );
460
488
result->buffer_colors .emplace_back ();
489
+ // overlay is white, if present
490
+ result->buffer_colors .emplace_back (true , video::SColor (0xFFFFFFFF ));
461
491
// Items with inventory images do not need shading
462
492
result->needs_shading = false ;
463
493
} else if (def.type == ITEM_NODE) {
464
494
if (f.mesh_ptr [0 ]) {
465
495
mesh = cloneMesh (f.mesh_ptr [0 ]);
466
496
scaleMesh (mesh, v3f (0.12 , 0.12 , 0.12 ));
497
+ postProcessNodeMesh (mesh, f, false , false , nullptr ,
498
+ &result->buffer_colors );
467
499
} else {
468
500
switch (f.drawtype ) {
469
501
case NDT_PLANTLIKE: {
470
502
mesh = getExtrudedMesh (tsrc,
471
- tsrc->getTextureName (f.tiles [0 ].layers [0 ].texture_id ));
503
+ tsrc->getTextureName (f.tiles [0 ].layers [0 ].texture_id ),
504
+ tsrc->getTextureName (f.tiles [0 ].layers [1 ].texture_id ));
505
+ // Add color
506
+ const TileLayer &l0 = f.tiles [0 ].layers [0 ];
507
+ result->buffer_colors .emplace_back (l0.has_color , l0.color );
508
+ const TileLayer &l1 = f.tiles [0 ].layers [1 ];
509
+ result->buffer_colors .emplace_back (l1.has_color , l1.color );
472
510
break ;
473
511
}
474
512
case NDT_PLANTLIKE_ROOTED: {
475
513
mesh = getExtrudedMesh (tsrc,
476
- tsrc->getTextureName (f.special_tiles [0 ].layers [0 ].texture_id ));
514
+ tsrc->getTextureName (f.special_tiles [0 ].layers [0 ].texture_id ), " " );
515
+ // Add color
516
+ const TileLayer &l0 = f.special_tiles [0 ].layers [0 ];
517
+ result->buffer_colors .emplace_back (l0.has_color , l0.color );
477
518
break ;
478
519
}
479
520
case NDT_NORMAL:
@@ -484,6 +525,9 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
484
525
mesh = cloneMesh (cube);
485
526
cube->drop ();
486
527
scaleMesh (mesh, v3f (1.2 , 1.2 , 1.2 ));
528
+ // add overlays
529
+ postProcessNodeMesh (mesh, f, false , false , nullptr ,
530
+ &result->buffer_colors );
487
531
break ;
488
532
}
489
533
default : {
@@ -507,6 +551,10 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
507
551
material1.setTexture (3 , material2.getTexture (3 ));
508
552
material1.MaterialType = material2.MaterialType ;
509
553
}
554
+ // add overlays (since getMesh() returns
555
+ // the base layer only)
556
+ postProcessNodeMesh (mesh, f, false , false , nullptr ,
557
+ &result->buffer_colors );
510
558
}
511
559
}
512
560
}
@@ -524,36 +572,49 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
524
572
525
573
rotateMeshXZby (mesh, -45 );
526
574
rotateMeshYZby (mesh, -30 );
527
-
528
- postProcessNodeMesh (mesh, f, false , false , nullptr , &result->buffer_colors );
529
575
}
530
576
result->mesh = mesh;
531
577
}
532
578
533
579
534
580
535
- scene::SMesh *getExtrudedMesh (ITextureSource *tsrc, const std::string &imagename)
581
+ scene::SMesh *getExtrudedMesh (ITextureSource *tsrc,
582
+ const std::string &imagename, const std::string &overlay_name)
536
583
{
584
+ // check textures
537
585
video::ITexture *texture = tsrc->getTextureForMesh (imagename);
538
586
if (!texture) {
539
- return nullptr ;
587
+ return NULL ;
540
588
}
589
+ video::ITexture *overlay_texture =
590
+ (overlay_name.empty ()) ? NULL : tsrc->getTexture (overlay_name);
541
591
592
+ // get mesh
542
593
core::dimension2d<u32 > dim = texture->getSize ();
543
594
scene::IMesh *original = g_extrusion_mesh_cache->create (dim);
544
595
scene::SMesh *mesh = cloneMesh (original);
545
596
original->drop ();
546
597
547
- // Customize material
548
- video::SMaterial &material = mesh->getMeshBuffer (0 )->getMaterial ();
549
- material.setTexture (0 , tsrc->getTexture (imagename));
550
- material.TextureLayer [0 ].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
551
- material.TextureLayer [0 ].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
552
- material.setFlag (video::EMF_BILINEAR_FILTER, false );
553
- material.setFlag (video::EMF_TRILINEAR_FILTER, false );
554
- material.setFlag (video::EMF_BACK_FACE_CULLING, true );
555
- material.setFlag (video::EMF_LIGHTING, false );
556
- material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
598
+ // set texture
599
+ mesh->getMeshBuffer (0 )->getMaterial ().setTexture (0 ,
600
+ tsrc->getTexture (imagename));
601
+ if (overlay_texture) {
602
+ scene::IMeshBuffer *copy = cloneMeshBuffer (mesh->getMeshBuffer (0 ));
603
+ copy->getMaterial ().setTexture (0 , overlay_texture);
604
+ mesh->addMeshBuffer (copy);
605
+ copy->drop ();
606
+ }
607
+ // Customize materials
608
+ for (u32 layer = 0 ; layer < mesh->getMeshBufferCount (); layer++) {
609
+ video::SMaterial &material = mesh->getMeshBuffer (layer)->getMaterial ();
610
+ material.TextureLayer [0 ].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
611
+ material.TextureLayer [0 ].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
612
+ material.setFlag (video::EMF_BILINEAR_FILTER, false );
613
+ material.setFlag (video::EMF_TRILINEAR_FILTER, false );
614
+ material.setFlag (video::EMF_BACK_FACE_CULLING, true );
615
+ material.setFlag (video::EMF_LIGHTING, false );
616
+ material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
617
+ }
557
618
scaleMesh (mesh, v3f (2.0 , 2.0 , 2.0 ));
558
619
559
620
return mesh;
0 commit comments