Hello,
I have a big lack of optimizations in my tiled zone system.
I would like to make a really infinite ground that we can edit with the mouse.
Here is how I build the mesh to be tiled :
Code: Select all
SMesh *newMesh = new SMesh();
video::SColor color(0xFFFFFFFF);
SMeshBuffer* mb;
for (f32 e = 0.0f; e < 10; e += 2.0f) {
for (f32 i = 0.0f; i < 10; i += 2.0f) {
mb = new SMeshBuffer();
mb->Vertices.push_back(video::S3DVertex( -50+50*e, 0 , 50+50*i, 1, 1, 1, color ,0 ,0));
mb->Vertices.push_back(video::S3DVertex( 50+50*e, 0 , 50+50*i, 1, 1, 1, color ,1 ,0));
mb->Vertices.push_back(video::S3DVertex( 50+50*e, 0 , -50+50*i, 1, 1, 1, color ,1 ,1));
mb->Vertices.push_back(video::S3DVertex( -50+50*e, 0 , -50+50*i, 1, 1, 1, color ,0 ,1));
mb->Indices.push_back(0);
mb->Indices.push_back(1);
mb->Indices.push_back(2);
mb->Indices.push_back(0);
mb->Indices.push_back(2);
mb->Indices.push_back(3);
//mb->getMaterial().setTexture(0,grassTexture);
mb->recalculateBoundingBox();
newMesh->addMeshBuffer(mb);
}
for (f32 i = 0.0f; i < 10; i += 2.0f) {
mb = new SMeshBuffer();
mb->Vertices.push_back(video::S3DVertex( -50-50*e, 0 , 50+50*i, 1, 1, 1, color ,0 ,0));
mb->Vertices.push_back(video::S3DVertex( 50-50*e, 0 , 50+50*i, 1, 1, 1, color ,1 ,0));
mb->Vertices.push_back(video::S3DVertex( 50-50*e, 0 , -50+50*i, 1, 1, 1, color ,1 ,1));
mb->Vertices.push_back(video::S3DVertex( -50-50*e, 0 , -50+50*i, 1, 1, 1, color ,0 ,1));
mb->Indices.push_back(0);
mb->Indices.push_back(1);
mb->Indices.push_back(2);
mb->Indices.push_back(0);
mb->Indices.push_back(2);
mb->Indices.push_back(3);
//mb->getMaterial().setTexture(0,grassTexture);
mb->recalculateBoundingBox();
newMesh->addMeshBuffer(mb);
}
for (f32 i = 0.0f; i < 10; i += 2.0f) {
mb = new SMeshBuffer();
mb->Vertices.push_back(video::S3DVertex( -50+50*e, 0 , 50-50*i, 1, 1, 1, color ,0 ,0));
mb->Vertices.push_back(video::S3DVertex( 50+50*e, 0 , 50-50*i, 1, 1, 1, color ,1 ,0));
mb->Vertices.push_back(video::S3DVertex( 50+50*e, 0 , -50-50*i, 1, 1, 1, color ,1 ,1));
mb->Vertices.push_back(video::S3DVertex( -50+50*e, 0 , -50-50*i, 1, 1, 1, color ,0 ,1));
mb->Indices.push_back(0);
mb->Indices.push_back(1);
mb->Indices.push_back(2);
mb->Indices.push_back(0);
mb->Indices.push_back(2);
mb->Indices.push_back(3);
//mb->getMaterial().setTexture(0,grassTexture);
mb->recalculateBoundingBox();
newMesh->addMeshBuffer(mb);
}
for (f32 i = 0.0f; i < 10; i += 2.0f) {
mb = new SMeshBuffer();
mb->Vertices.push_back(video::S3DVertex( -50-50*e, 0 , 50-50*i, 1, 1, 1, color ,0 ,0));
mb->Vertices.push_back(video::S3DVertex( 50-50*e, 0 , 50-50*i, 1, 1, 1, color ,1 ,0));
mb->Vertices.push_back(video::S3DVertex( 50-50*e, 0 , -50-50*i, 1, 1, 1, color ,1 ,1));
mb->Vertices.push_back(video::S3DVertex( -50-50*e, 0 , -50-50*i, 1, 1, 1, color ,0 ,1));
mb->Indices.push_back(0);
mb->Indices.push_back(1);
mb->Indices.push_back(2);
mb->Indices.push_back(0);
mb->Indices.push_back(2);
mb->Indices.push_back(3);
//mb->getMaterial().setTexture(0,grassTexture);
mb->recalculateBoundingBox();
newMesh->addMeshBuffer(mb);
}
}
newMesh->recalculateBoundingBox();
return (IMesh*)newMesh;
I never knew why when I place it, I have to do like it's a 900*900 mesh...
I need to make a lot of meshBuffers so that we can change the texture of any square we want.
And here is how I tile it :
Code: Select all
void zoneMemoryUpdate() {
// Get the player's position.
vector3df pPos = CedCamera->getNode()->getPosition();
// And we find a zone to unload.
for (size_t i = 0; i < CedZones.size(); i++) {
f32 dist = CedZones[i]->getPosition().getDistanceFrom(pPos);
if (dist > 2500) {
// We are too far from this zone, remove it !
for (u32 n = 0; n < CedZones[i]->getNodesCount(); n++) {
IMeshSceneNode *sn = (IMeshSceneNode*)CedZones[i]->getNode(n);
// Get it's meshBuffer.
for (u32 a = 0; a < sn->getMesh()->getMeshBufferCount(); a++) {
// Now, remove the meshBuffer stucked in the memory !
CedDriver->removeHardwareBuffer(sn->getMesh()->getMeshBuffer(a));
sn->getMesh()->getMeshBuffer(a)->drop();
}
// Remove the zone's mesh.
CedScene->getMeshCache()->removeMesh(sn->getMesh());
sn->getMesh()->drop();
// Remove node
sn->remove();
CedZones[i]->removeNode(sn);
}
}
}
// Find a zone to load.
// Get the nearest multiple of 900.
f32 nearestX = pPos.X;
f32 nearestZ = pPos.Z;
nearestX = nearestX/900;
nearestX = floor(nearestX);
nearestX = nearestX * 900;
nearestZ = nearestZ/900;
nearestZ = floor(nearestZ);
nearestZ = nearestZ * 900;
// Make the positions to look at.
array<vector3df> checkLocations;
checkLocations.push_back(vector3df(nearestX, 0, nearestZ));
checkLocations.push_back(vector3df(nearestX, 0, nearestZ + 900));
checkLocations.push_back(vector3df(nearestX, 0, nearestZ - 900));
checkLocations.push_back(vector3df(nearestX + 900, 0, nearestZ));
checkLocations.push_back(vector3df(nearestX - 900, 0, nearestZ));
checkLocations.push_back(vector3df(nearestX + 900, 0, nearestZ + 900));
checkLocations.push_back(vector3df(nearestX + 900, 0, nearestZ - 900));
checkLocations.push_back(vector3df(nearestX - 900, 0, nearestZ + 900));
checkLocations.push_back(vector3df(nearestX - 900, 0, nearestZ - 900));
// Now, find the zones having at least one of these coordinates.
for (size_t i = 0; i < CedZones.size(); i++) {
for (size_t z = 0; z < checkLocations.size(); z++) {
//if (CedZones[i]->getPosition() == checkLocations[z])
if (CedZones[i]->getPosition().getDistanceFrom(checkLocations[z]) < 900)
checkLocations.erase(z);
}
}
// Now, we load each zone from what we've found.
if (CedZones.size() != 0) {
for (size_t x = 0; x < checkLocations.size(); x++) {
Ced_Zone *newZone = new Ced_Zone(checkLocations[x]);
CedZones.push_back(newZone);
}
}
}
Does anyone have an idea please ?
Thanks for your help.