Jump to content

  • Log In with Google      Sign In   
  • Create Account

Problem calculating normals


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 robustpotato   Members   -  Reputation: 124

Like
0Likes
Like

Posted 10 March 2011 - 06:54 PM

I am trying to calculate the vertex normals for my random terrain generation. I am fine on the logic (i think). I am using the method where 1st I work out the surface normals of each triangle and use an average of adjacent triangles to get the vertex normal.
The problem is not with the calculations. Rather the fact that the program crashes.

I get the following dialog after running

"Windows has triggered a breakpoint in RenderEngine.exe.

This may be due to a corruption of the heap, which indicates a bug in RenderEngine.exe or any of the DLLs it has loaded.


This may also be due to the user pressing F12 while RenderEngine.exe has focus.

The output window may have more diagnostic information.
t".

Here is the method:


D3DXVECTOR3* Terrain::CalculateSurfaceNormals(TerrainVertex* verts)
{
	D3DXVECTOR3* triangleNormals = new D3DXVECTOR3[((width-1) * (length-1))];

	for (int x = 0; x < width-1; x++)
	{	
		for (int z = 0; z < length-1; z++)
		{
			int i0,i1,i2,i3;
			//calculate the 4 indices of this quad
			i0 =	x+(z*width);		
			i1 =	(x+1)+z*width;		
			i2 =	(x)+(z+1)*width;		
			i3 =	(x+1)+(z+1)*width;	

			// ###############
			//triangle 1
			D3DXVECTOR3 v1 = *new D3DXVECTOR3(verts[i0].x,verts[i0].y,verts[i0].z);	
			D3DXVECTOR3 v2 = *new D3DXVECTOR3(verts[i1].x,verts[i1].y,verts[i1].z);		
			D3DXVECTOR3 v3 = *new D3DXVECTOR3(verts[i2].x,verts[i2].y,verts[i2].z);		

			D3DXVECTOR3 e1 = v2-v1;
			D3DXVECTOR3 e2 = v3-v1;

			//CROSS PRODUCT
			D3DXVECTOR3 cross;
			cross.x = e1.y*e2.z - e1.z*e2.y;
			cross.y = e1.z*e2.x - e1.x*e2.z;
			cross.z = e1.x*e2.y - e1.y*e2.x;

			//NORMALIZE THE VECTOR
			float magnitude = sqrt((cross.x * cross.x) +(cross.y * cross.y) + (cross.z * cross.z));
			cross.x /= magnitude;
			cross.z /= magnitude;
			cross.y /= magnitude;
	
			triangleNormals[(2*x) + ((z) * (2*(width-1)))] = cross;

			//############
			////triangle 2
			D3DXVECTOR3 v1_2 =  v3;	
			D3DXVECTOR3 v2_2 =  v2;		
			D3DXVECTOR3 v3_2 =  *new D3DXVECTOR3(verts[i3].x, verts[i3].y, verts[i3].z);	

			D3DXVECTOR3 e1_2 = v2_2-v1_2;
			D3DXVECTOR3 e2_2 = v3_2-v1_2;
			
						//CROSS PRODUCT
			D3DXVECTOR3 cross_2;
			cross_2.x = e1_2.y*e2_2.z - e1_2.z*e2_2.y;
			cross_2.y = e1_2.z*e2_2.x - e1_2.x*e2_2.z;
			cross_2.z = e1_2.x*e2_2.y - e1_2.y*e2_2.x;

						//NORMALIZE THE VECTOR
			float magnitude_2 = sqrt((cross_2.x * cross_2.x) +(cross_2.y * cross_2.y) + (cross_2.z * cross_2.z));
			cross_2.x /= magnitude_2;
			cross_2.z /= magnitude_2;
			cross_2.y /= magnitude_2;
	
			triangleNormals[(2*x) + ((z) * (2*(width-1))) + 1] = cross_2;

		}
	}
	return triangleNormals;

}

additional info:
- currently the terrain grid is 64*64, ideally id want to go bigger when i program optimization.
- when it crashes it is about halfway through the nested loop x =34, y = 0
- the code is executed at the start of the program. during initialization and not in the game loop


Im not the most advanced when it comes to c++, i can only imagine its a memory problem.

I think the logic is correct (its late) but if you see any please make me aware because I would hate to get it running and see the wrong results.




thank you for your time.

Sponsor:

#2 Hodgman   Moderators   -  Reputation: 31843

Like
0Likes
Like

Posted 10 March 2011 - 07:03 PM

Firstly, you're leaking a ton of memory. Remove all of those "* new" snippets!
i.e. replace:
D3DXVECTOR3 v3_2 = *new D3DXVECTOR3(verts[i3].x, verts[i3].y, verts[i3].z);
with:
D3DXVECTOR3 v3_2 = D3DXVECTOR3(verts[i3].x, verts[i3].y, verts[i3].z);


What is the logic behind this index calculation?
triangleNormals[(2*x) + ((z) * (2*(width-1)))] = cross;
The index values that you're calculating seem to go outside the range of that array allocation (i.e. you're calculating indices greater than "((width-1) * (length-1))"), which will be causing the heap corruption.


I'd reccommend using assertions whenever doing something like this, to ensure that your indices never go out of bounds. E.g.
int arraySize = ((width-1) * (length-1));
D3DXVECTOR3* triangleNormals = new D3DXVECTOR3[arraySize];
...
int index =
(2*x) + ((z) * (2*(width-1)));
assert( index < arraySize )
triangleNormals[index] = cross;


#3 robustpotato   Members   -  Reputation: 124

Like
0Likes
Like

Posted 10 March 2011 - 07:38 PM

Firstly, you're leaking a ton of memory. Remove all of those "* new" snippets!
i.e. replace:
D3DXVECTOR3 v3_2 = *new D3DXVECTOR3(verts[i3].x, verts[i3].y, verts[i3].z);
with:
D3DXVECTOR3 v3_2 = D3DXVECTOR3(verts[i3].x, verts[i3].y, verts[i3].z);


I will give that a try thanks.


What is the logic behind this index calculation?
triangleNormals[(2*x) + ((z) * (2*(width-1)))] = cross;
The index values that you're calculating seem to go outside the range of that array allocation (i.e. you're calculating indices greater than "((width-1) * (length-1))"), which will be causing the heap corruption.


i see i didn't make the array big enough should be *2

ok ill try explain my thinking

width and height are the width and height in vertices so width-1 is the number of polys on the grid.

i multiply it by 2 as there are 2 triangles on every grid square.

multiply that by the z to get the index of the triangle at the start of this row.

now ad 2x, to get to the current position in this row (again its doubled because of there being 2 triangles on each row




my array should be like this


D3DXVECTOR3* triangleNormals = new D3DXVECTOR3[((width-1) * (length-1))* 2];



Ive come from Java and c#,.
Ive heard stuff here and there about memory leakage. what i hear is c++ needs more care when dealing with memory.
i was unaware that using new would cause this problem. Ive made ammendments as you recommended.
Would declaring the vectors outside the loop have the same effect/improve it. since its the same memory location getting re-used.
or was that just totally wrong?

Thanks for the help though i will try immediately.




#4 TheUnbeliever   Members   -  Reputation: 961

Like
0Likes
Like

Posted 10 March 2011 - 08:31 PM

Ive heard stuff here and there about memory leakage. what i hear is c++ needs more care when dealing with memory.
i was unaware that using new would cause this problem. Ive made ammendments as you recommended.
Would declaring the vectors outside the loop have the same effect/improve it. since its the same memory location getting re-used.
or was that just totally wrong?


When you new something, you must also delete it when you are done (ditto new[] and delete[]). delete works by taking a pointer to a chunk of memory allocated by new and which has not yet been deleted. When you do "... = * new..." you lose the pointer that new returned and consequently cannot deallocate this memory - you lose it until your program dies and the operating system reclaims all of its resources.

The key difference in this aspect is that C# and Java are both garbage collected and will automatically perform that deallocation for you when they detect you are no longer using it (roughly, when no references to it remain). However, you don't normally need to allocate memory on the heap everywhere in C++ - you can allocate things on the stack by simply not using new, as shown above. Finally, there are things called smart pointers - classes which emulate the general interface of a pointer but which will try to provide automatic memory management for you (by reference counting or otherwise).
[TheUnbeliever]

#5 robustpotato   Members   -  Reputation: 124

Like
1Likes
Like

Posted 11 March 2011 - 05:28 AM

Right. Thanks for the info. I made the amendments given by Hodgman and got rid of the *new snippits. Also the other problem you pointed out to me with my logic seemed fine, i double the size of the array as I said.

Heres the results :







Posted Image Posted Image




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS