Level of Detail

Discussion about everything. New games, 3d math, development tips...
devsh
Competition winner
Posts: 2057
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

then sorry if you already got the idea
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

The not editing the vertices is a good idea though, but wouldn't it be better to remove the vertices I don't need? Or are you saying to always use the same vertices and just different indices?
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

Ok, here is an update of code. Please post any comments.

Code: Select all

class CSampleSceneNode : public scene::ISceneNode
{

	class Vertex;
	class Triangle;
	class Triangle {
	public:
		Vertex* vertex[3];
		Triangle(Vertex* v1, Vertex* v2, Vertex* v3) {
			vertex[0] = v1;
			vertex[1] = v2;
			vertex[2] = v3;
			for (int x = 0; x < 3; x++) {
				vertex[x]->face.push_back(this);
				for (int y = 0; y < 3; y++) {
					bool add = true;
					for(int i = 0; i < vertex[x]->neighbors.size(); i++) {
						if (vertex[y]->position == vertex[x]->neighbors[i]->position) {
							add = false;			
						}
					}
					if (add) {
						vertex[x]->neighbors.push_back(vertex[y]);

					}
				}
			}
		}
		bool HasVertex(Vertex* v) { return (v->position == vertex[0]->position || v->position == vertex[1]->position || v->position == vertex[2]->position); };
		void ReplaceVertex(Vertex* target, Vertex* v) {
			for (int x = 0; x < 3; x++)
				if (vertex[x]->position == target->position) {
					vertex[x] = v;
					std::cout << "REPLACE" << std::endl;
				}
		}
		bool CheckAndRemove(int num, array<Triangle*> *list) {
			if (vertex[0]->position == vertex[1]->position || vertex[1]->position == vertex[2]->position || vertex[2]->position == vertex[0]->position) {
				list->erase(num);
				return true;
			}
		}
	};
	class Vertex {
	public:
		vector3df position;
		array<Vertex*> neighbors;
		array<Triangle*> face;
		int id;
	};

	class TriangleMesh {
	public:
		array<Triangle> mesh;
		void AddTriangle(Triangle tri) {
			mesh.push_back(tri);
		}
		void Remove(short num) {
			mesh.erase(num,1);
		}
	};


	IMeshBuffer* BuildMeshBufferFromTriangles(IMeshBuffer* oldmb, array<Triangle*> arr, array<Vertex*>ver) {
		SMeshBuffer* newm = new SMeshBuffer();
		newm->Material = oldmb->getMaterial();
		u16* indices = new u16[arr.size()*3];
		for (int x = 0; x < arr.size(); x++) {
			for (int y = 0; y < 3; y++) {
				indices[x*3+y] = arr[x]->vertex[y]->id;
			}
		}
		newm->append(oldmb->getVertices(),oldmb->getVertexCount(),indices,arr.size()*3);
		return newm;
	}



	IMesh* DefaultMesh;
	IMesh** LODMesh;
	IMesh* CurrentMesh;
	IMeshBuffer* test;
	char CurrentLevel;
	char LevelCount;
	float LODBegin;
	float LODLast;
	bool LODOn;
	array<Vertex*> Verts[8];
	array<Triangle*> Tris[8];
public:

	CSampleSceneNode(IMesh* mesh, scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, int numOfCollapseOnLast, char numOfLevels = 4, float LODBeginDist = 10, float LODLastDist = 30)
		: scene::ISceneNode(parent, mgr, id)
	{
		DefaultMesh = mesh;
		CurrentMesh = mesh;
		CurrentMesh->getMeshBuffer(0)->getMaterial().Wireframe = true;
		LODBegin = LODBeginDist;
		LODLast = LODLastDist;
		LevelCount = numOfLevels;
		CurrentLevel = 0;
		LODMesh = new IMesh*[numOfLevels];
		LODOn = true;

		for (int x = 0; x < mesh->getMeshBufferCount(); x++) {
			S3DVertex* verts = (S3DVertex*)mesh->getMeshBuffer(x)->getVertices();
			std::cout << mesh->getMeshBuffer(x)->getVertexCount() << std::endl;
			for (int y = 0; y < mesh->getMeshBuffer(x)->getVertexCount(); y++) {
				Vertex* vert = new Vertex();
				vert->position = verts[y].Pos;
				vert->id = y;
				Verts[x].push_back(vert);
			}
				
		}
		
		for (int x = 0; x < mesh->getMeshBufferCount(); x++) {
			u16* indices = mesh->getMeshBuffer(x)->getIndices();
			std::cout << mesh->getMeshBuffer(x)->getIndexCount() << std::endl;
			for (int y = 0; y < mesh->getMeshBuffer(x)->getIndexCount(); y += 3) {
				Triangle *tri = new Triangle(Verts[x][indices[y]],Verts[x][indices[y+1]],Verts[x][indices[y+2]]);

				Tris[x].push_back(tri);
			}
				
		}
		array<int> nr;
		for (int x = 0; x < 80; x++) {

			if (Tris[0][x]->HasVertex(Verts[0][0])) {
				Tris[0][x]->ReplaceVertex(Verts[0][0],Verts[0][10]);
				nr.push_back(x);
			}
	
		}
		for (int x = 0; x < nr.size(); x++) {
			
			if (Tris[0][nr[x]]->CheckAndRemove(nr[x],&Tris[0])) {
				x--;
				std::cout << "REMOVED" << std::endl;
			}
			
		}

		test = BuildMeshBufferFromTriangles(mesh->getMeshBuffer(0),Tris[0],Verts[0]);


		

	}

	
	virtual void OnRegisterSceneNode()
	{
		if (IsVisible)
			SceneManager->registerNodeForRendering(this);

		ISceneNode::OnRegisterSceneNode();
	}


	virtual void render()
	{
		if (LODOn) {
			vector3df cameraPos = SceneManager->getActiveCamera()->getPosition();
			f32 dist = AbsoluteTransformation.getTranslation().getDistanceFrom(cameraPos);
			CurrentLevel = 0;
			float increment = (LODLast-LODBegin)/LevelCount;
			for (int x = 0; x < LevelCount; x++) {
				if (dist >= (LODBegin+increment*x)*(LODBegin+increment*x))
					CurrentLevel = x;
			}
		}
		else
			CurrentMesh = DefaultMesh;
		IVideoDriver* driver = SceneManager->getVideoDriver();
		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		for (int x = 0; x < CurrentMesh->getMeshBufferCount(); x++) {
			driver->setMaterial(CurrentMesh->getMeshBuffer(x)->getMaterial());
			driver->drawMeshBuffer(test);
		}
	}
	
	virtual const core::aabbox3d<f32>& getBoundingBox() const
	{
		return CurrentMesh->getBoundingBox();
	}

	void setLODOn(bool on) { LODOn = on; };
	bool getLODOn() { return LODOn; };

};
I'm having some problems with the vertices. When I load a model with 42 vertices, in irrlicht it says it has 174! Is this intentional? If so, what can I do to change it?[/code]
Post Reply