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.html. Unfortunately it just reaffirmed that I'm probably doing something stupid without giving me any direction. Here is the octree class:
Header:
Expand|Select|Wrap|Line Numbers
- #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);
- };
Expand|Select|Wrap|Line Numbers
- #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);
- }
Expand|Select|Wrap|Line Numbers
- 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:
Expand|Select|Wrap|Line Numbers
- 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..
Expand|Select|Wrap|Line Numbers
- 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