Advertisement

program not running because of arrays...

Started by January 23, 2005 02:50 AM
13 comments, last by adam17 19 years, 10 months ago
ok, ONCE again im in need of some help. this time its something different lol. anyway, im trying to build a struct for an octree. inside of my struct (as u can see) i have an array for the 8 internal cubes of a cube.

struct cube
{
	float3 upperlim;
	float3 lowerlim;
	float3 center;
	float width;
	int num_vertex;
	int MAX_vertex;

	vector<float3> vertices;

	bool InternalCubes;
	//cube *node[8];
	//vector<cube> node;

	cube();
	void Load(vector<float> array);
	void Draw();
	void Sort();
}Cube;
of the 2 lines that are commented i have tried several different ways of defining an array inside of the struct. ive tried:

cube *node;        //its resized as node=new cube[8] in constructor
cube *node[8];
vector<cube> node; //its resized in the constructor
when i compile the program and run it, it compiles and links ok but the program will not run. the message box for running in fullscreen or windowed mode doesnt even come up. any ideas of what im doing wrong?
It isn't possible to allocate a object that way. An easy way to see why is to look at the folowing code:

struct A{  A *next;  A() { next = New A; }};


Now when one declares a A object memory will be allocated for the next pointer, then the constructor is called and a new A object is created and it's adress is set to next. This new A object also has a constructor that tells it to set its next pointer to a new A object that also has a constructor... and so it continues for an eternity (well, until you run out of memory). So this isn't allowed, for the same reason neither is A next[8].

What you need to do is make a octreehandler, that controls the allocation of new cubes. Something like this:

struct A{  A *next;};class AHandler{  A root;  void GrowTree() { root.next = new A; }};


Hope this helps, and I hope you don't mind my spelling ;)

Edit: The GrowThree() functions is of course incredible simplified (to the point that it doesn't even work for growing the tree beyond the root and one branch) but it should give you an idea on how it can be done. In the real thing you'll of course have to take into account re-linking and such (so not to lose the rest of the tree).

[Edited by - Spearhawk on January 23, 2005 3:30:34 AM]
Advertisement
To my knowledge, there is another problem as well: can structures even HAVE constructors or member functions? I thought that was something only classes could do. Although now that I test it..it seems to indicate that that is valid...odd....can someone explain this? it is definatly contradictory to the C++ books I have read....
i knew i was missing something, that extra object for the tree.

thanks alot! im gonna give that a try and ill tell you guys how it works!
Quote: Original post by Steve132
To my knowledge, there is another problem as well: can structures even HAVE constructors or member functions? I thought that was something only classes could do. Although now that I test it..it seems to indicate that that is valid...odd....can someone explain this? it is definatly contradictory to the C++ books I have read....


IIRC in C++ structs are essentially classes where all the members are public by default. Books usually fail to mention this, possibly to avoid confusion when it comes to legacy code using C structs (which are different from C++ structs), which cannot have member functions.
the rug - funpowered.com
i fully made an octree the other day which was quite impressive handling the x,y,z axis each on its own ie it fitted perfectly around the world!

Firstly not every child will have a 8 children so set that to
node *child;

then if the current node has say less than 50 polygons inside then you stop creating its children and set IsEndNode = true;

i could give you the source code!!?

Regards Dawid
----------------------------

http://djoubert.co.uk
Advertisement
dawidjoubert: octtree will always have 8 children or none. OCT = 8.
adam17: I would prefer to have just Node **child. You also don't need InternalCubes/IsEndNode flag. You just check child pointer. If it's NULL then it's leaf node. And what is MAX_vertex?
You should never let your fears become the boundaries of your dreams.
i have done a bit of revising and i cant get past a list of errors pointing to the 5 lines towards the end of the sort function:
temp.node[nodeLevel].numVertex++;			temp.node[nodeLevel].vertices.resize(temp.node[nodeLevel].numVertex);			temp.node[nodeLevel].vertices[temp.node[nodeLevel].numVertex-1].x = vertices[x].x;			temp.node[nodeLevel].vertices[temp.node[nodeLevel].numVertex-1].y = vertices[x].y;			temp.node[nodeLevel].vertices[temp.node[nodeLevel].numVertex-1].z = vertices[x].z;


here are the errors im getting:
--------------------Configuration: Box Physics - Win32 Release--------------------Compiling...main.cppE:\Adam\Software\Visual C++\Box Physics\Octree.h(101) : error C2228: left of '.numVertex' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(102) : error C2228: left of '.vertices' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(102) : error C2228: left of '.resize' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(102) : error C2228: left of '.numVertex' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(103) : error C2228: left of '.vertices' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(103) : error C2228: left of '.numVertex' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(103) : error C2228: left of '.x' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(103) : error C2109: subscript requires array or pointer typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(103) : error C2228: left of '.x' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(104) : error C2228: left of '.vertices' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(104) : error C2228: left of '.numVertex' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(104) : error C2228: left of '.y' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(104) : error C2109: subscript requires array or pointer typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(104) : error C2228: left of '.y' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(105) : error C2228: left of '.vertices' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(105) : error C2228: left of '.numVertex' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(105) : error C2228: left of '.z' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(105) : error C2109: subscript requires array or pointer typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(105) : error C2228: left of '.z' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(109) : error C2228: left of '.numVertex' must have class/struct/union typeE:\Adam\Software\Visual C++\Box Physics\Octree.h(112) : error C2664: 'Sort' : cannot convert parameter 1 from 'struct _node *' to 'struct _node'        No constructor could take the source type, or constructor overload resolution was ambiguousE:\Adam\Software\Visual C++\Box Physics\main.cpp(219) : error C2664: 'Sort' : cannot convert parameter 1 from 'struct _node *' to 'struct _node'        No constructor could take the source type, or constructor overload resolution was ambiguousError executing cl.exe.Box Physics.exe - 22 error(s), 0 warning(s)


here is the entire file
const int MAX_VERTEX = 100;struct float3{	float x, y, z;	float d;	void mag();};void float3::mag(){	d=sqrt((x*x)+(y*y)+(z*z));}struct _node{	float3			center;	bool			isFull;	int				level;	int				numVertex;	vector<float3>	vertices;	_node	*node[8];};struct _cube{	float3 upperlim;	float3 lowerlim;		float3 center;		//center of root cube	float width;		//width of root cube	int numVertex;	vector<float3> vertices;	bool isFull;	_node *node[8];	_cube();	void Load(vector<float> array);	void Draw();};_cube::_cube(){	isFull = false;	numVertex = 0;	upperlim.x = upperlim.y = upperlim.z = 0;	lowerlim.x = lowerlim.y = lowerlim.z = 0;}void Sort(_node temp){	int nodeLevel;	if(temp.numVertex > MAX_VERTEX)	{		for(int x=0; x<temp.numVertex; x++)		{			nodeLevel = 8;			if(temp.vertices[x].x < temp.center.x)				if(temp.vertices[x].y < temp.center.y)					if(temp.vertices[x].z < temp.center.z)					{						nodeLevel = 0;					}					else					{						nodeLevel = 1;					}				else					if(temp.vertices[x].z < temp.center.z)					{						nodeLevel = 2;					}					else					{						nodeLevel = 3;					}			else				if(temp.vertices[x].y < temp.center.y)					if(temp.vertices[x].z < temp.center.z)					{						nodeLevel = 4;					}					else					{						nodeLevel = 5;					}				else					if(temp.vertices[x].z < temp.center.z)					{						nodeLevel = 6;					}					else					{						nodeLevel = 7;					}			temp.node[nodeLevel].numVertex++;			temp.node[nodeLevel].vertices.resize(temp.node[nodeLevel].numVertex);			temp.node[nodeLevel].vertices[temp.node[nodeLevel].numVertex-1].x = vertices[x].x;			temp.node[nodeLevel].vertices[temp.node[nodeLevel].numVertex-1].y = vertices[x].y;			temp.node[nodeLevel].vertices[temp.node[nodeLevel].numVertex-1].z = vertices[x].z;		}		for(x=0; x<8; x++)		{			if(temp.node[x].numVertex > MAX_VERTEX)			{				temp.isFull = true;				Sort(temp.node[x]);			}		}	}}void _cube::Load(vector<float> array){	numVertex = array.size()/3;		vertices.resize(numVertex);	for(int x=0; x<numVertex; x++)	{		vertices[x].x = array[3*x];		vertices[x].y = array[3*x+1];		vertices[x].z = array[3*x+2];	}	for(x=0; x<numVertex; x++)		vertices[x].mag();	for(x=0; x<numVertex; x++)	{		if(lowerlim.x > vertices[x].x)			lowerlim.x = vertices[x].x;		if(lowerlim.y > vertices[x].y)			lowerlim.y = vertices[x].y;		if(lowerlim.z > vertices[x].z)			lowerlim.z = vertices[x].z;		if(upperlim.x < vertices[x].x)			upperlim.x = vertices[x].x;		if(upperlim.y < vertices[x].y)			upperlim.y = vertices[x].y;		if(upperlim.z < vertices[x].z)			upperlim.z = vertices[x].z;	}		float xlen = upperlim.x - lowerlim.x;	float ylen = upperlim.y - lowerlim.y;	float zlen = upperlim.z - lowerlim.z;	if(xlen>ylen)		if(xlen>zlen)			width=xlen;		else			width=zlen;	else		if(ylen>zlen)			width=ylen;		else			width=zlen;	center.x = (upperlim.x + lowerlim.x) / 2;	center.y = (upperlim.y + lowerlim.y) / 2;	center.z = (upperlim.z + lowerlim.z) / 2;	//Sort();}void _cube::Draw(){	float w = width/2;	glDisable(GL_LIGHTING);	glDisable(GL_TEXTURE_2D);	glPointSize(15);	glColor3f(1, 0, 0);	glBegin(GL_POINTS);		glVertex3f(center.x, center.y, center.z);	glEnd();	glColor4f(1, 1, 0, 1);	glLineWidth(1);	glBegin(GL_LINE_LOOP);		glVertex3f(center.x-w, center.y-w, center.z-w);//lowerlim.x, lowerlim.y, lowerlim.z);		glVertex3f(center.x+w, center.y-w, center.z-w);//upperlim.x, lowerlim.y, lowerlim.z);		glVertex3f(center.x+w, center.y+w, center.z-w);//upperlim.x, upperlim.y, lowerlim.z);		glVertex3f(center.x-w, center.y+w, center.z-w);//lowerlim.x, upperlim.y, lowerlim.z);	glEnd();	glBegin(GL_LINE_LOOP);		glVertex3f(center.x-w, center.y-w, center.z+w);//lowerlim.x, lowerlim.y, upperlim.z);		glVertex3f(center.x+w, center.y-w, center.z+w);//upperlim.x, lowerlim.y, upperlim.z);		glVertex3f(center.x+w, center.y+w, center.z+w);//upperlim.x, upperlim.y, upperlim.z);		glVertex3f(center.x-w, center.y+w, center.z+w);//lowerlim.x, upperlim.y, upperlim.z);	glEnd();	glBegin(GL_LINES);		glVertex3f(center.x-w, center.y-w, center.z-w);		glVertex3f(center.x-w, center.y-w, center.z+w);		glVertex3f(center.x+w, center.y-w, center.z-w);		glVertex3f(center.x+w, center.y-w, center.z+w);		glVertex3f(center.x-w, center.y+w, center.z-w);		glVertex3f(center.x-w, center.y+w, center.z+w);		glVertex3f(center.x+w, center.y+w, center.z-w);		glVertex3f(center.x+w, center.y+w, center.z+w);	glEnd();	glEnable(GL_LIGHTING);	glEnable(GL_TEXTURE_2D);}


keep in mind this is just a test to get the tree up and running so ive spared myself alot of the math involving polygons and im just using points right now.

as always optimization tips are very much appreciated!
Bunch of questions/comments...
1) Why does float3 have 'd'. I know it's length but its also wasting space in 99% cases.
2) You are missing pointer in bunch of places (use -> instead of .) ... (can you spot replacement in point 4)
3) Ths part of code...
temp.node[nodeLevel].vertices.resize(temp.node[nodeLevel].numVertex);temp.node[nodeLevel].vertices[temp.node[nodeLevel].numVertex-1].x = vertices[x].x;temp.node[nodeLevel].vertices[temp.node[nodeLevel].numVertex-1].y = vertices[x].y;temp.node[nodeLevel].vertices[temp.node[nodeLevel].numVertex-1].z = vertices[x].z;

...can be writen as...
temp.node[nodeLevel]->vertices.push_back( vertices[x] );

...a bit cleaner :).
4) isFull falg is still useless.
5) You will have to rewrite the whole thing if you actualy want to use this as octree for triangles as you only sort vertices.

Writing a good octree is not a simple task. I remember I had bunch of troubles the first time. But after everything 'clicks' in the place it just works. And after writing that, other structures like quadtrees/ATBs are much easyer to understand, but they still have their fare share of code. ATB in my case has +3k lines in over 10 files not even counting anything about actual drawing, VA/VBO manegment and stuff like that.
You should never let your fears become the boundaries of your dreams.
ok i have gotten rid of ALOT of errors and now im stuck with the last two. they deal with passing the node back into the sort function. i know im missing like a single character or something.

also can anybody see a way, if its possible, to combine my _node and _cube structures?

_DarkWIng_
i put the d in my float3 struct so when i add to it, and make it a polygon structure, i will have the distance formula precalculated for collision detection. any reasons why it shouldnt be there still?

This topic is closed to new replies.

Advertisement