Redesigning mesh class(need expert advice)

Started by
5 comments, last by Basiror 18 years, 3 months ago
Hi, I plan to redesign my mesh class today The basic concept of the mesh class is to help the data for my renderer however I want to reuse the code in my map editor as well so I thouht I could derive a mesh_editable from the basic mesh class e.g.:

class mesh
{
public:
private:
 // vectors of vertices, uvarrays, indexarray, vector of texture
 // effectclasses applied to this mesh
}

/*
each effect class describes some effect that is associated with the mesh
e.g.: a certain vertex/pixel shader effect
or rendering grass onto the surface of the mesh which required the mesh class as input to adjust the grass to the topology of the surface
*/

/*
at loading time a shader class is bound to the effect class to determine the quality of the scene, the shader class does the rendering the effect class delivers the information used by the shaderclass to render the effect e.g.: positions normals tangents ....
*/


Now since I want to reuse it in my editor I had to derive another class mesh_editable to apply transformations .... deletions ... It requires the following - each vertex needs a flag to see if it is selected - each face needs a selection flag - transformation of one vertex needs to transform the surrounding faces - semi brush based geometry, meaning it is created as brush based geometry but handled as triangulated data - edges must be splitable so i can subdivide a mesh by hand to refine it - the whole object must be renderable at decent speeds so my idea was to implement all this in the child class and whenever I am done with manipulations and deselect the mesh it does a recompile to make it fit into the basic mesh class and can be rendered with no effort so each mesh_editable has its own rendering routine to render the object during manipulation The point is how do I implement the whole thing with flags ...? One way I thought of is the use a std::pair < vertex/face, property class> and store this information in a std::vector but how do i handle vertex selections that affect multiple faces? should i store vertices in a seperate array and use indices as face coordinates? so accessing a vertex looks like that?: m_Vertices[ facepair.first.m_uiVertex[0]] ? the still leaves the question how to handle edges? should i represent them as part of the face class? if so how would i handle edge splits of edges shared with multiple faces the only solutions that makes sense to me is a vector as we know it from vectices m_Edges[facepair.first.edgem_uiEdges[0]] do you think this amount of indirection is a good solution or do you know another solution that could handle the requirements without this nasty couplying of classes? This approach I presented above means a lot of work and might be pretty error sensitive buts the only decent implementation i could come up that fulfills the requirements Thx to everyone who takes the time to read this post [Edited by - Basiror on December 17, 2005 11:45:46 AM]
http://www.8ung.at/basiror/theironcross.html
Advertisement
My advice with the selections is to store a list of selected objects, referenced by name (or id number preferably for speed), and be clever about how you store point selections. Something I have noticed Maya does is to list point selections in ranges, e.g. Selected: mesh1.vtx[0-100],mesh1.vtx[102],mesh1.vtx[105-190]. So when the user selected a bunch of vertices, parse them into ranges and just store the ranges.
Most functions in your editing program are going to be geared towards working on just the selected set, so it makes sense to store a list of everything that is selected, so you don't have to parse your whole scene each time.
You could store both ofcourse (a flag per object, and a selected list) so you get quickest indexing either way, but that would require more maintainance.
I store the selected flag so I can render the vertices with a different color to make it visible otherwise I had to traverse the selection list and dereference a ton of pointers which might make the code pretty hard to read :)

Yes I definitely store the selected vertices as a triple

I wrote a little helper class just like std::pair but with 3 elements

cross::triple<uint32,uint32,uint32>(objectindex,startrange,endrange);

I have just setup the mesh_editable class and i think the design is pretty robust and extentable

any further suggestions ?

thx in advance
http://www.8ung.at/basiror/theironcross.html
Have you thought about using a ready made scene graph? Writing a neat graph of your own that can handle a lot of different geometric types can be quite tricky and time consuming (if its just plain meshes it wouldn't be too bad, but I would imagine material specs, lights, animation etc would be desirable eventually). You could just use a scene graph to organise your editor, and export in a format which can then be imported into your game directly by your own classes.
Not really, a premade scenegraph would work with my planned culling system I think


its a mixture of quadtree octree portals and a few other neat things to minimize overdraw and network bandwidth usage,

The editor will only handle meshes and brush base geometry, where the brush based geometry is placed and on creation of the brush i convert it into a mesh object

the whole clipping tolls you needed in earlier times to create low poly maps became quite useless the last years

a decent mesh representation with vertex selection movement and face deletion/insertion is the way to go i think

which has the neat side effect that you don t have to worry about artifacts caused by grid snaps


in my scene representation
i have some sort of scene node
this node holds static meshes , models... entities lights...

i will use per object shadow maps to shade everything indoor

each light holds a identifier to see which object it has an effect on

and then i simply render the shadow map

this is done at the end of the rendering queue

btw I had a look at your engine code
do you have icq?

mine is 82015598 maybe we could talk there I have some nice sources you might want to use in your engine
http://www.8ung.at/basiror/theironcross.html
Check your PM.
So I have implemented the vertex selection deselection cycling, well at least I think it works that way.
Just to share the principle with others who might somewhen discover this thread:

Aim of the following algorithm:
Precondition: each following mouseclick/ray hits the same vertices
1) Each selection ray touches n vertices
2) You select the vertices iteratively with each following mouse click until there are no more vertices left
3) Now you iteratively deselect one vertex at a time at each mouse click

Elaboration:
1) create a list of all vertices that are hit by the ray
2) compare this list with the vertex list of the old/last ray
3) see if we are in selection cycle, if so select the first unselected vertex
4) if we could no find any unselected vertices we switch modes 5)
5) switch mode from selection to deselection m_bSwitchSelection = true; see underneath
6) now deselect the first selected vertex in the current ray_list

The same code is provided underneath to reconstruct what I explained in the above lines, once this is done and working I will write a little article about it and post it on gamedev.net

//select vertex in 3d		void select_vertex(const vector3d& vecCamPos, const vector3d& vecPickDir, float32 flRadius, uint32array& a)		{			uint32 i;			float32 flDistance;			vector3d vecNewPos;			vector3d vecNewDir;			vector3d vecPnt;			plane pl;			ray_list	rl;						//clear the index selection array			a.clear();			//check all vertices if they are on the ray			for(i=0;i<m_Vertices.size();i++)			{				if(vertex_on_ray(i,vecCamPos,vecPickDir,flRadius,flDistance) == true)				{					rl.push_back(vertex_selection_pair(i,flDistance));				}			}			//then sort them by distance			rl.sort(ray_list_distance());			//if these lists aren t equal the vertex selection deselection cycle is broken and 			//we need to start a new cycle			if(equal_ray_list(m_LastRayList,rl) == false)				m_bSelectionSwitch = false;			//now select the first element that is not yet selected if we are in the selection cycle			for(ray_list::iterator iterJ=rl.begin(); iterJ!=rl.end(), m_bSelectionSwitch==false; iterJ++)			{				if(m_Vertices[iterJ->first].third.selected() == false)				{					m_Vertices[iterJ->first].third.select();					m_LastRayList = rl;					//add vertex to selection					a.push_back(iterJ->first);										return;				}			}			//if no unselected vertex was found lets start the deselection cycle			m_bSelectionSwitch = true;			//now deselect the first vertex that is selected			for(ray_list::iterator iterJ=rl.begin(); iterJ!=rl.end(); iterJ++)			{				if(m_Vertices[iterJ->first].third.selected() == true)				{					m_Vertices[iterJ->first].third.deselect();					m_LastRayList = rl;									return;				}			}		};


Merry Christmas
http://www.8ung.at/basiror/theironcross.html

This topic is closed to new replies.

Advertisement