Skip to content

Commit

Permalink
Replace object visual by enum
Browse files Browse the repository at this point in the history
  • Loading branch information
cx384 committed Jan 15, 2025
1 parent cf074dd commit d5757fe
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 128 deletions.
256 changes: 135 additions & 121 deletions src/client/content_cao.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
if (!m_prop.is_visible)
return;

infostream << "GenericCAO::addToScene(): " << m_prop.visual << std::endl;
infostream << "GenericCAO::addToScene(): " << es_ObjectVisual[m_prop.visual].str << std::endl;

m_material_type_param = 0.5f; // May cut off alpha < 128 depending on m_material_type

Expand Down Expand Up @@ -634,140 +634,154 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
node->forEachMaterial(setMaterial);
};

if (m_prop.visual == "sprite") {
grabMatrixNode();
m_spritenode = m_smgr->addBillboardSceneNode(
m_matrixnode, v2f(1, 1), v3f(0,0,0), -1);
m_spritenode->grab();
video::ITexture *tex = tsrc->getTextureForMesh("no_texture.png");
m_spritenode->forEachMaterial([tex] (auto &mat) {
mat.setTexture(0, tex);
});
switch(m_prop.visual) {
case OBJECTVISUAL_SPRITE: {
grabMatrixNode();
m_spritenode = m_smgr->addBillboardSceneNode(
m_matrixnode, v2f(1, 1), v3f(0,0,0), -1);
m_spritenode->grab();
video::ITexture *tex = tsrc->getTextureForMesh("no_texture.png");
m_spritenode->forEachMaterial([tex] (auto &mat) {
mat.setTexture(0, tex);
});

setSceneNodeMaterials(m_spritenode);
setSceneNodeMaterials(m_spritenode);

m_spritenode->setSize(v2f(m_prop.visual_size.X,
m_prop.visual_size.Y) * BS);
{
const float txs = 1.0 / 1;
const float tys = 1.0 / 1;
setBillboardTextureMatrix(m_spritenode,
txs, tys, 0, 0);
}
} else if (m_prop.visual == "upright_sprite") {
grabMatrixNode();
auto mesh = make_irr<scene::SMesh>();
f32 dx = BS * m_prop.visual_size.X / 2;
f32 dy = BS * m_prop.visual_size.Y / 2;
video::SColor c(0xFFFFFFFF);

video::S3DVertex vertices[4] = {
video::S3DVertex(-dx, -dy, 0, 0,0,1, c, 1,1),
video::S3DVertex( dx, -dy, 0, 0,0,1, c, 0,1),
video::S3DVertex( dx, dy, 0, 0,0,1, c, 0,0),
video::S3DVertex(-dx, dy, 0, 0,0,1, c, 1,0),
};
if (m_is_player) {
// Move minimal Y position to 0 (feet position)
for (auto &vertex : vertices)
vertex.Pos.Y += dy;
m_spritenode->setSize(v2f(m_prop.visual_size.X,
m_prop.visual_size.Y) * BS);
{
const float txs = 1.0 / 1;
const float tys = 1.0 / 1;
setBillboardTextureMatrix(m_spritenode,
txs, tys, 0, 0);
}
}
const u16 indices[] = {0,1,2,2,3,0};

for (int face : {0, 1}) {
auto buf = make_irr<scene::SMeshBuffer>();
// Front (0) or Back (1)
if (face == 1) {
for (auto &v : vertices)
v.Normal *= -1;
for (int i : {0, 2})
std::swap(vertices[i].Pos, vertices[i+1].Pos);
break;
case OBJECTVISUAL_UPRIGHT_SPRITE: {
grabMatrixNode();
auto mesh = make_irr<scene::SMesh>();
f32 dx = BS * m_prop.visual_size.X / 2;
f32 dy = BS * m_prop.visual_size.Y / 2;
video::SColor c(0xFFFFFFFF);

video::S3DVertex vertices[4] = {
video::S3DVertex(-dx, -dy, 0, 0,0,1, c, 1,1),
video::S3DVertex( dx, -dy, 0, 0,0,1, c, 0,1),
video::S3DVertex( dx, dy, 0, 0,0,1, c, 0,0),
video::S3DVertex(-dx, dy, 0, 0,0,1, c, 1,0),
};
if (m_is_player) {
// Move minimal Y position to 0 (feet position)
for (auto &vertex : vertices)
vertex.Pos.Y += dy;
}
buf->append(vertices, 4, indices, 6);
const u16 indices[] = {0,1,2,2,3,0};

for (int face : {0, 1}) {
auto buf = make_irr<scene::SMeshBuffer>();
// Front (0) or Back (1)
if (face == 1) {
for (auto &v : vertices)
v.Normal *= -1;
for (int i : {0, 2})
std::swap(vertices[i].Pos, vertices[i+1].Pos);
}
buf->append(vertices, 4, indices, 6);

// Set material
setMaterial(buf->getMaterial());
buf->getMaterial().ColorParam = c;
// Set material
setMaterial(buf->getMaterial());
buf->getMaterial().ColorParam = c;

// Add to mesh
mesh->addMeshBuffer(buf.get());
}
// Add to mesh
mesh->addMeshBuffer(buf.get());
}

mesh->recalculateBoundingBox();
m_meshnode = m_smgr->addMeshSceneNode(mesh.get(), m_matrixnode);
m_meshnode->grab();
} else if (m_prop.visual == "cube") {
grabMatrixNode();
scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
m_meshnode = m_smgr->addMeshSceneNode(mesh, m_matrixnode);
m_meshnode->grab();
mesh->drop();
mesh->recalculateBoundingBox();
m_meshnode = m_smgr->addMeshSceneNode(mesh.get(), m_matrixnode);
m_meshnode->grab();
}
break;
case OBJECTVISUAL_CUBE: {
grabMatrixNode();
scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
m_meshnode = m_smgr->addMeshSceneNode(mesh, m_matrixnode);
m_meshnode->grab();
mesh->drop();

m_meshnode->setScale(m_prop.visual_size);
m_meshnode->setScale(m_prop.visual_size);

setSceneNodeMaterials(m_meshnode);
setSceneNodeMaterials(m_meshnode);

m_meshnode->forEachMaterial([this] (auto &mat) {
mat.BackfaceCulling = m_prop.backface_culling;
});
} else if (m_prop.visual == "mesh") {
grabMatrixNode();
scene::IAnimatedMesh *mesh = m_client->getMesh(m_prop.mesh, true);
if (mesh) {
if (!checkMeshNormals(mesh)) {
infostream << "GenericCAO: recalculating normals for mesh "
<< m_prop.mesh << std::endl;
m_smgr->getMeshManipulator()->
recalculateNormals(mesh, true, false);
}
m_meshnode->forEachMaterial([this] (auto &mat) {
mat.BackfaceCulling = m_prop.backface_culling;
});
}
break;
case OBJECTVISUAL_MESH: {
grabMatrixNode();
scene::IAnimatedMesh *mesh = m_client->getMesh(m_prop.mesh, true);
if (mesh) {
if (!checkMeshNormals(mesh)) {
infostream << "GenericCAO: recalculating normals for mesh "
<< m_prop.mesh << std::endl;
m_smgr->getMeshManipulator()->
recalculateNormals(mesh, true, false);
}

m_animated_meshnode = m_smgr->addAnimatedMeshSceneNode(mesh, m_matrixnode);
m_animated_meshnode->grab();
mesh->drop(); // The scene node took hold of it
m_animated_meshnode->animateJoints(); // Needed for some animations
m_animated_meshnode->setScale(m_prop.visual_size);
m_animated_meshnode = m_smgr->addAnimatedMeshSceneNode(mesh, m_matrixnode);
m_animated_meshnode->grab();
mesh->drop(); // The scene node took hold of it
m_animated_meshnode->animateJoints(); // Needed for some animations
m_animated_meshnode->setScale(m_prop.visual_size);

// set vertex colors to ensure alpha is set
setMeshColor(m_animated_meshnode->getMesh(), video::SColor(0xFFFFFFFF));
// set vertex colors to ensure alpha is set
setMeshColor(m_animated_meshnode->getMesh(), video::SColor(0xFFFFFFFF));

setSceneNodeMaterials(m_animated_meshnode);
setSceneNodeMaterials(m_animated_meshnode);

m_animated_meshnode->forEachMaterial([this] (auto &mat) {
mat.BackfaceCulling = m_prop.backface_culling;
});
} else
errorstream<<"GenericCAO::addToScene(): Could not load mesh "<<m_prop.mesh<<std::endl;
} else if (m_prop.visual == "wielditem" || m_prop.visual == "item") {
grabMatrixNode();
ItemStack item;
if (m_prop.wield_item.empty()) {
// Old format, only textures are specified.
infostream << "textures: " << m_prop.textures.size() << std::endl;
if (!m_prop.textures.empty()) {
infostream << "textures[0]: " << m_prop.textures[0]
<< std::endl;
IItemDefManager *idef = m_client->idef();
item = ItemStack(m_prop.textures[0], 1, 0, idef);
}
} else {
infostream << "serialized form: " << m_prop.wield_item << std::endl;
item.deSerialize(m_prop.wield_item, m_client->idef());
m_animated_meshnode->forEachMaterial([this] (auto &mat) {
mat.BackfaceCulling = m_prop.backface_culling;
});
} else
errorstream<<"GenericCAO::addToScene(): Could not load mesh "<<m_prop.mesh<<std::endl;
}
m_wield_meshnode = new WieldMeshSceneNode(m_smgr, -1);
m_wield_meshnode->setItem(item, m_client,
(m_prop.visual == "wielditem"));
break;
case OBJECTVISUAL_WIELDITEM_ITEM:
case OBJECTVISUAL_ITEM: {
grabMatrixNode();
ItemStack item;
if (m_prop.wield_item.empty()) {
// Old format, only textures are specified.
infostream << "textures: " << m_prop.textures.size() << std::endl;
if (!m_prop.textures.empty()) {
infostream << "textures[0]: " << m_prop.textures[0]
<< std::endl;
IItemDefManager *idef = m_client->idef();
item = ItemStack(m_prop.textures[0], 1, 0, idef);
}
} else {
infostream << "serialized form: " << m_prop.wield_item << std::endl;
item.deSerialize(m_prop.wield_item, m_client->idef());
}
m_wield_meshnode = new WieldMeshSceneNode(m_smgr, -1);
m_wield_meshnode->setItem(item, m_client,
(m_prop.visual == OBJECTVISUAL_WIELDITEM_ITEM));

m_wield_meshnode->setScale(m_prop.visual_size / 2.0f);
} else {
infostream<<"GenericCAO::addToScene(): \""<<m_prop.visual
<<"\" not supported"<<std::endl;
m_wield_meshnode->setScale(m_prop.visual_size / 2.0f);
}
break;
default:
infostream << "GenericCAO::addToScene(): \""
<< es_ObjectVisual[m_prop.visual].str
<< "\" not supported"<<std::endl;
break;
}

/* Set VBO hint */
// wieldmesh sets its own hint, no need to handle it
if (m_meshnode || m_animated_meshnode) {
// sprite uses vertex animation
if (m_meshnode && m_prop.visual != "upright_sprite")
if (m_meshnode && m_prop.visual != OBJECTVISUAL_UPRIGHT_SPRITE)
m_meshnode->getMesh()->setHardwareMappingHint(scene::EHM_STATIC);

if (m_animated_meshnode) {
Expand Down Expand Up @@ -873,7 +887,7 @@ void GenericCAO::updateLight(u32 day_night_ratio)

void GenericCAO::setNodeLight(const video::SColor &light_color)
{
if (m_prop.visual == "wielditem" || m_prop.visual == "item") {
if (m_prop.visual == OBJECTVISUAL_WIELDITEM_ITEM || m_prop.visual == OBJECTVISUAL_ITEM) {
if (m_wield_meshnode)
m_wield_meshnode->setNodeLightColor(light_color);
return;
Expand Down Expand Up @@ -1259,7 +1273,7 @@ void GenericCAO::updateTexturePos()
}

else if (m_meshnode) {
if (m_prop.visual == "upright_sprite") {
if (m_prop.visual == OBJECTVISUAL_UPRIGHT_SPRITE) {
int row = m_tx_basepos.Y;
int col = m_tx_basepos.X;

Expand Down Expand Up @@ -1293,7 +1307,7 @@ void GenericCAO::updateTextures(std::string mod)
m_current_texture_modifier = mod;

if (m_spritenode) {
if (m_prop.visual == "sprite") {
if (m_prop.visual == OBJECTVISUAL_SPRITE) {
std::string texturestring = "no_texture.png";
if (!m_prop.textures.empty())
texturestring = m_prop.textures[0];
Expand All @@ -1312,7 +1326,7 @@ void GenericCAO::updateTextures(std::string mod)
}

else if (m_animated_meshnode) {
if (m_prop.visual == "mesh") {
if (m_prop.visual == OBJECTVISUAL_MESH) {
for (u32 i = 0; i < m_animated_meshnode->getMaterialCount(); ++i) {
const auto texture_idx = m_animated_meshnode->getMesh()->getTextureSlot(i);
if (texture_idx >= m_prop.textures.size())
Expand Down Expand Up @@ -1350,7 +1364,7 @@ void GenericCAO::updateTextures(std::string mod)
}

else if (m_meshnode) {
if(m_prop.visual == "cube")
if(m_prop.visual == OBJECTVISUAL_CUBE)
{
for (u32 i = 0; i < 6; ++i)
{
Expand All @@ -1371,7 +1385,7 @@ void GenericCAO::updateTextures(std::string mod)
use_anisotropic_filter);
});
}
} else if (m_prop.visual == "upright_sprite") {
} else if (m_prop.visual == OBJECTVISUAL_UPRIGHT_SPRITE) {
scene::IMesh *mesh = m_meshnode->getMesh();
{
std::string tname = "no_texture.png";
Expand Down Expand Up @@ -1563,7 +1577,7 @@ bool GenericCAO::visualExpiryRequired(const ObjectProperties &new_) const
*/

bool uses_legacy_texture = new_.wield_item.empty() &&
(new_.visual == "wielditem" || new_.visual == "item");
(new_.visual == OBJECTVISUAL_WIELDITEM_ITEM || new_.visual == OBJECTVISUAL_ITEM);
// Ordered to compare primitive types before std::vectors
return old.backface_culling != new_.backface_culling ||
old.is_visible != new_.is_visible ||
Expand Down Expand Up @@ -1954,7 +1968,7 @@ void GenericCAO::updateMeshCulling()
if (!node)
return;

if (m_prop.visual == "upright_sprite") {
if (m_prop.visual == OBJECTVISUAL_UPRIGHT_SPRITE) {
// upright sprite has no backface culling
node->forEachMaterial([=] (auto &mat) {
mat.FrontfaceCulling = hidden;
Expand Down
Loading

0 comments on commit d5757fe

Please sign in to comment.