Hello everyone,
I've been a regular of this forum but this is my first post, generally I can find the answer to my question already, but this time I'm having a somewhat specific problem.
For fun I've been working on making a 3d game (who hasn't haha) and while it's nothing special at the moment I was making some decent headway. I'm working on constructing an octree for my triangle data, but I keep getting this pesky bad_alloc runtime error. I've looked up online for more information on it, including this post here on TheScripts http://www.thescripts. com/forum/thread523575.ht ml. Unfortunately it just reaffirmed that I'm probably doing something stupid without giving me any direction. Here is the octree class:
Header:
and the source file
the offending line is:
Line 163 from the source.
Any small level of impressiveness that might've been achieved by this code is negated by the fact that I did it following very closely this guide on xbdev.net: http://www.xbdev.net/maths_of_3d/octree/tutorial/index.php
The output from debug reads:
I'm fairly sure the error in code is here and not in the implementation from the engine, and so I've neglected to post that here. Mostly because I was able to call new on the bool arrays which precede this call. I added the lines:
which were not present in the original source at xbdev.net. Not that I assumed I was a better programmer but because I thought it was right. Even commenting this out I get the same error at the same location.
Please forgive my poor programming style. I am pretty noobish.
If anyone can help me narrow down my problem I'd be greatly appreciative. If you've read this far, I thank you for reading this cumbersome post ^^;;
-Ally
I've been a regular of this forum but this is my first post, generally I can find the answer to my question already, but this time I'm having a somewhat specific problem.
For fun I've been working on making a 3d game (who hasn't haha) and while it's nothing special at the moment I was making some decent headway. I'm working on constructing an octree for my triangle data, but I keep getting this pesky bad_alloc runtime error. I've looked up online for more information on it, including this post here on TheScripts http://www.thescripts. com/forum/thread523575.ht ml. Unfortunately it just reaffirmed that I'm probably doing something stupid without giving me any direction. Here is the octree class:
Header:
Code:
#pragma once
#include <d3dx9.h>
#include <d3d9.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "d3d9.lib")
class czOctree
{
public:
czOctree( );
~czOctree( ) { }
void Release( );
void Create(D3DXVECTOR3* pVerts, int iNumVerticies);
private:
static const int maxNodes = 3;
static const int minNumTriangles = 250;
protected:
int numVerticies;
D3DXVECTOR3* pVerticies;
D3DXVECTOR3 center;
float diameter;
bool containsTriangles;
czOctree* oChildren[8];
enum octreeParts { TOP_FRONT_LEFT, TOP_FRONT_RIGHT, TOP_BACK_LEFT, TOP_BACK_RIGHT,
BOTTOM_FRONT_LEFT, BOTTOM_FRONT_RIGHT, BOTTOM_BACK_LEFT, BOTTOM_BACK_RIGHT };
inline float abs_f(float f) { if(f<0) return -f; return f; };
inline D3DXVECTOR3 GetNodeCenter(D3DXVECTOR3 currentCenter, float fDiameter, int iWhichNode);
void SetData(D3DXVECTOR3* pVerts, int numVerts);
void SetNode(D3DXVECTOR3* pVerts, int numVerts);
void CreateNode(D3DXVECTOR3* pVerts, int numVerts, D3DXVECTOR3 vCenter, float fDiameter);
void CreateNodeEnd(D3DXVECTOR3* pTotalVerts, int NumTotalVerts, bool* pBools, D3DXVECTOR3 vCenter, float fDiameter, int iTriangles, int iWhichNode);
};
Code:
#include "octrees.h"
const bool DEBUG = true;
#define DMSGBOX( a ) { if(DEBUG) MessageBox(NULL, a, "DEBUG", 0); }
#define DMSGFILE( file, a ) { if(DEBUG && f.is_open()) file << a << std::endl; }
int g_currentLevel;
czOctree::czOctree( )
{
numVerticies = NULL;
pVerticies = NULL;
center = D3DXVECTOR3(0,0,0);
diameter = 0.0f;
ZeroMemory(oChildren, sizeof(oChildren));
}
void czOctree::SetData(D3DXVECTOR3 *pVerts, int numVerts)
{
if( pVerts == NULL || numVerts == 0 )
return;
for(int i=0; i<numVerts; i++)
{
center.x = center.x + pVerts[i].x;
center.y = center.y + pVerts[i].y;
center.z = center.z + pVerts[i].z;
}
center.x = center.x / (float)numVerts;
center.y = center.y / (float)numVerts;
center.z = center.z / (float)numVerts;
float widthMax = 0.0f;
float heightMax = 0.0f;
float depthMax = 0.0f;
for(int i=0; i<numVerts; i++)
{
float width = abs_f(pVerts[i].x - center.x);
float height = abs_f(pVerts[i].y - center.y);
float depth = abs_f(pVerts[i].z - center.z);
if( width > widthMax ) widthMax = width;
if( height > heightMax ) heightMax = height;
if( depth > depthMax ) depthMax = depth;
}
widthMax *= 2;
heightMax *= 2;
depthMax *= 2;
diameter = max( widthMax, max(heightMax,depthMax) );
}
void czOctree::CreateNode(D3DXVECTOR3 *pVerts, int numVerts, D3DXVECTOR3 vCenter, float fDiameter)
{
center = vCenter;
int numTriangles = numVerts / 3;
diameter = fDiameter;
if( (numTriangles < minNumTriangles) || (g_currentLevel >= maxNodes) )
{
SetNode(pVerts, numVerts);
containsTriangles = true;
}
else
{
containsTriangles = false;
bool* pBoolArray1 = new bool[numTriangles];
bool* pBoolArray2 = new bool[numTriangles];
bool* pBoolArray3 = new bool[numTriangles];
bool* pBoolArray4 = new bool[numTriangles];
bool* pBoolArray5 = new bool[numTriangles];
bool* pBoolArray6 = new bool[numTriangles];
bool* pBoolArray7 = new bool[numTriangles];
bool* pBoolArray8 = new bool[numTriangles];
ZeroMemory(pBoolArray1, numTriangles);
ZeroMemory(pBoolArray2, numTriangles);
ZeroMemory(pBoolArray3, numTriangles);
ZeroMemory(pBoolArray4, numTriangles);
ZeroMemory(pBoolArray5, numTriangles);
ZeroMemory(pBoolArray6, numTriangles);
ZeroMemory(pBoolArray7, numTriangles);
ZeroMemory(pBoolArray8, numTriangles);
D3DXVECTOR3 cntr = center;
for(int i=0; i< numVerts; i++)
{
D3DXVECTOR3 point = pVerts[i];
if((point.y >= cntr.y) && (point.x <= cntr.x) && (point.z >= cntr.z) )
pBoolArray1[i/3] = true;
if( (point.y >= cntr.y) && (point.x >= cntr.x) && (point.z >= cntr.z) )
pBoolArray2[i/3] = true;
if( (point.y >= cntr.y) && (point.x <= cntr.x) && (point.z <= cntr.z) )
pBoolArray3[i/3] = true;
if( (point.y >= cntr.y) && (point.x >= cntr.x) && (point.z <= cntr.z) )
pBoolArray4[i/3] = true;
if( (point.y <= cntr.y) && (point.x <= cntr.x) && (point.z >= cntr.z) )
pBoolArray5[i/3] = true;
if( (point.y <= cntr.y) && (point.x >= cntr.x) && (point.z >= cntr.z) )
pBoolArray6[i/3] = true;
if( (point.y <= cntr.y) && (point.x <= cntr.x) && (point.z <= cntr.z) )
pBoolArray7[i/3] = true;
if( (point.y <= cntr.y) && (point.x >= cntr.x) && (point.z <= cntr.z) )
pBoolArray8[i/3] = true;
}
int iCount1, iCount2, iCount3, iCount4, iCount5, iCount6, iCount7, iCount8;
iCount1 = iCount2 = iCount3 = iCount4 = iCount5 = iCount6 = iCount7 = iCount8 = 0;
for(int i=0; i<numTriangles; i++)
{
if(pBoolArray1[i]) iCount1++;
if(pBoolArray2[i]) iCount2++;
if(pBoolArray3[i]) iCount3++;
if(pBoolArray4[i]) iCount4++;
if(pBoolArray5[i]) iCount5++;
if(pBoolArray6[i]) iCount6++;
if(pBoolArray7[i]) iCount7++;
if(pBoolArray8[i]) iCount8++;
}
CreateNodeEnd(pVerts, numVerts, pBoolArray1, cntr, fDiameter, iCount1, TOP_FRONT_LEFT );
CreateNodeEnd(pVerts, numVerts, pBoolArray2, cntr, fDiameter, iCount2, TOP_FRONT_RIGHT);
CreateNodeEnd(pVerts, numVerts, pBoolArray3, cntr, fDiameter, iCount3, TOP_BACK_LEFT);
CreateNodeEnd(pVerts, numVerts, pBoolArray4, cntr, fDiameter, iCount4, TOP_BACK_RIGHT);
CreateNodeEnd(pVerts, numVerts, pBoolArray5, cntr, fDiameter, iCount5, BOTTOM_FRONT_LEFT);
CreateNodeEnd(pVerts, numVerts, pBoolArray6, cntr, fDiameter, iCount6, BOTTOM_FRONT_RIGHT);
CreateNodeEnd(pVerts, numVerts, pBoolArray7, cntr, fDiameter, iCount7, BOTTOM_BACK_LEFT);
CreateNodeEnd(pVerts, numVerts, pBoolArray8, cntr, fDiameter, iCount8, BOTTOM_BACK_RIGHT);
delete[] pBoolArray1;
delete[] pBoolArray2;
delete[] pBoolArray3;
delete[] pBoolArray4;
delete[] pBoolArray5;
delete[] pBoolArray6;
delete[] pBoolArray7;
delete[] pBoolArray8;
}
}
void czOctree::CreateNodeEnd(D3DXVECTOR3 *pTotalVerts, int NumTotalVerts, bool *pBools, D3DXVECTOR3 vCenter, float fDiameter, int iTriangles, int iWhichNode)
{
if( iTriangles = 0 )
return;
D3DXVECTOR3* nodeVerts = new D3DXVECTOR3[iTriangles*3];
int count = 0;
for(int i=0; i<NumTotalVerts; i++)
{
if( pBools[i/3] )
{
nodeVerts[count] = pTotalVerts[i];
count++;
}
}
oChildren[iWhichNode] = new czOctree;
D3DXVECTOR3 newCenter = GetNodeCenter(vCenter, fDiameter, iWhichNode);
g_currentLevel++;
oChildren[iWhichNode]->CreateNode(nodeVerts, iTriangles*3, newCenter, fDiameter/2);
g_currentLevel--;
delete[] nodeVerts;
}
void czOctree::SetNode(D3DXVECTOR3 *pVerts, int numVerts)
{
containsTriangles = true;
numVerticies = numVerts;
pVerticies = new D3DXVECTOR3[numVerts];
ZeroMemory(pVerticies, sizeof(D3DXVECTOR3)*numVerticies);
memcpy(pVerticies, pVerts, sizeof(D3DXVECTOR3)*numVerticies);
}
D3DXVECTOR3 czOctree::GetNodeCenter(D3DXVECTOR3 currentCenter, float fDiameter, int iWhichNode)
{
D3DXVECTOR3 vCenter = currentCenter;
D3DXVECTOR3 vNewCenter = D3DXVECTOR3(0.0f,0.0f,0.0f);
float fDia = fDiameter;
switch(iWhichNode)
{
case TOP_FRONT_LEFT:
{ vNewCenter = D3DXVECTOR3( vCenter.x - fDia/4, vCenter.y + fDia/4, vCenter.z + fDia/4 );
break; }
case TOP_FRONT_RIGHT:
{ vNewCenter = D3DXVECTOR3( vCenter.x + fDia/4, vCenter.y + fDia/4, vCenter.z + fDia/4 );
break; }
case TOP_BACK_LEFT:
{ vNewCenter = D3DXVECTOR3( vCenter.x - fDia/4, vCenter.y + fDia/4, vCenter.z - fDia/4 );
break; }
case TOP_BACK_RIGHT:
{ vNewCenter = D3DXVECTOR3( vCenter.x + fDia/4, vCenter.y + fDia/4, vCenter.z - fDia/4 );
break; }
case BOTTOM_FRONT_LEFT:
{ vNewCenter = D3DXVECTOR3( vCenter.x - fDia/4, vCenter.y - fDia/4, vCenter.z + fDia/4 );
break; }
case BOTTOM_FRONT_RIGHT:
{ vNewCenter = D3DXVECTOR3( vCenter.x + fDia/4, vCenter.y - fDia/4, vCenter.z + fDia/4 );
break; }
case BOTTOM_BACK_LEFT:
{ vNewCenter = D3DXVECTOR3( vCenter.x - fDia/4, vCenter.y - fDia/4, vCenter.z - fDia/4 );
break; }
case BOTTOM_BACK_RIGHT:
{ vNewCenter = D3DXVECTOR3( vCenter.x + fDia/4, vCenter.y - fDia/4, vCenter.z - fDia/4 );
break; }
}
return vNewCenter;
}
void czOctree::Release( )
{
if(pVerticies)
{
delete[] pVerticies;
pVerticies = NULL;
}
for(int i=0; i<8; i++)
{
if( oChildren[i] )
{
oChildren[i]->Release( );
oChildren[i] = NULL;
}
}
}
void czOctree::Create(D3DXVECTOR3* pVerts, int iNumVerticies)
{
numVerticies = iNumVerticies;
SetData(pVerts, iNumVerticies);
CreateNode(pVerts, numVerticies, center, diameter);
}
Code:
oChildren[iWhichNode] = new czOctree;
Any small level of impressiveness that might've been achieved by this code is negated by the fact that I did it following very closely this guide on xbdev.net: http://www.xbdev.net/maths_of_3d/octree/tutorial/index.php
The output from debug reads:
Code:
First-chance exception at 0x7c91b3fb in zombie1.exe: 0xC0000005: Access violation reading location 0x44080000. First-chance exception at 0x7c81eb33 in zombie1.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0012fbc4.. Unhandled exception at 0x7c81eb33 in zombie1.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0012fbc4..
Code:
delete[] pBoolArray1; ... delete[] pBoolArray8;
Please forgive my poor programming style. I am pretty noobish.
If anyone can help me narrow down my problem I'd be greatly appreciative. If you've read this far, I thank you for reading this cumbersome post ^^;;
-Ally
Comment