//------------------------------------------------------------------//
//- class LIGHTNING ------------------------------------------------//
//------------------------------------------------------------------//
//- Simulates lightning --------------------------------------------//
//------------------------------------------------------------------//
//This class is used to generate the lightning
class SECTION
{
public:
SECTION(){pNext = NULL;}
~SECTION(){}
VECTOR3D Position;
float Energy;
SECTION * pNext;
};
class LIGHTNING
{
public:
LIGHTNING(){
//Some default values
active = false;
treshold = 0.5;
alpha = 1.41421356237; //sqrt2 usually looks good
NumSelections = 8;
line = false;
}
~LIGHTNING(){}
//Variables
//Orientation
VECTOR3D StartPos, EndPos;
//Behaviour
float Energy, alpha, dist, treshold;
bool active;
bool line;
int NumSelections;
//Functions
//Returns true if there was a strike
bool Update();
void SetPos(VECTOR3D Start, VECTOR3D End);
void AddEnergy(float x){Energy += x;}
};
//------------------------------------------------------------------//
//- LIGHTNING ENIGNE IMPLEMNENTATION -------------------------------//
//------------------------------------------------------------------//
//Used to delete SECTION linked lists
void deletelist(SECTION * pFirst)
{
//Some working variables
SECTION * pCurrent, * pNext;
if(pFirst)
{
pCurrent = pFirst;
while(pCurrent != NULL)
{
pNext = pCurrent->pNext;
delete pCurrent;
pCurrent = pNext;
}
}
}
void LIGHTNING::SetPos(VECTOR3D Start, VECTOR3D End)
{
StartPos.SetProperties(Start.v[0],Start.v[1],Start.v[2]);
EndPos.SetProperties(End.v[0],End.v[1],End.v[2]);
//Calculate distance squared
dist = (StartPos.v[0]-EndPos.v[0]) * (StartPos.v[0]-EndPos.v[0]) +
(StartPos.v[1]-EndPos.v[1]) * (StartPos.v[1]-EndPos.v[1]) +
(StartPos.v[2]-EndPos.v[2]) * (StartPos.v[0]-EndPos.v[2]);
}
bool LIGHTNING::Update()
{
if (active) // Draw the lightning
{
//Set up OGL
glPushMatrix();
glLoadIdentity();
//Some Variables
//Our linked list and pointers
SECTION * pNewList = NULL, * pCurrent = NULL,
* pNew = NULL, * pPossible = NULL, * CurSections = NULL;
//Some working variables
int x;
float y,b;
//Selection variables
int a = 1;
float z = 1;
//Start at the top - the first section
CurSections = new SECTION;
CurSections->Position.SetProperties(StartPos.v[0],StartPos.v[1],StartPos.v[2]);
CurSections->Energy = Energy * dist;
//Keep going until there are no more sections to be processed
while(CurSections)
{
//Make a list for the new selections
deletelist(pNewList);
pNewList = new SECTION;
pNew = pNewList;
//Go through every point on the current list
pCurrent = CurSections;
while (pCurrent)
{
if(pPossible)
delete[] pPossible;
pPossible = new SECTION [a];
//For every position create the next points
//Find our next points
b = 0;
for(x = 0; x < a; x++)
{
//Find the next points
pPossible[x].Position.SetProperties(cos(DEG_TO_RAD(rand()))+pCurrent->Position.v[0],
sin(DEG_TO_RAD(rand()))+pCurrent->Position.v[1],
-1 * sin(DEG_TO_RAD(rand()))+pCurrent->Position.v[2]);
//Assign random values
//Find break down number
//E = kQ/r^2
y = (((pPossible[x].Position.v[0] - EndPos.v[0])*(pPossible[x].Position.v[0] - EndPos.v[0])) +
((pPossible[x].Position.v[1] - EndPos.v[1])*(pPossible[x].Position.v[1] - EndPos.v[1])) +
((pPossible[x].Position.v[2] - EndPos.v[2])*(pPossible[x].Position.v[2] - EndPos.v[2])));
y = 9000000000/((rand()/RAND_MAX)*y*y*y);
pPossible[x].Energy = pow(y,alpha)*(rand()/RAND_MAX);
b += pPossible[x].Energy;
}
for(x = 0; x < a; x++)
{
//Distribute energy
//It is a percentage of the original
pPossible[x].Energy = pPossible[x].Energy/b * pCurrent->Energy;
//If energy less than threshold discard
if(pPossible[x].Energy > treshold)
{
//Assign the new point
pPossible[x].Position.v[0] = pPossible[x].Position.v[0] * pPossible[x].Energy;
pPossible[x].Position.v[1] = pPossible[x].Position.v[1] * pPossible[x].Energy;
pPossible[x].Position.v[2] = pPossible[x].Position.v[2] * pPossible[x].Energy;
//Draw from the previous to the current
glBegin(GL_LINES);
pCurrent->Position.SendToOGL();
pPossible[x].Position.SendToOGL();
glEnd();
//Add to new sections new sections
pNew->Position.SetProperties(pPossible[x].Position.v[0],
pPossible[x].Position.v[1],
pPossible[x].Position.v[2]);
if(pCurrent->pNext != NULL)//If you arn''t at the end
{
pNew->pNext = new SECTION;
pNew = pNew->pNext;
}
}
}
//Go to the next point
pCurrent = pCurrent->pNext;
}
//Remove the old selections and make the CurSelectiosn the new selection
deletelist(CurSections);
CurSections = pNewList;
//Update the amount of selections the next pass
z = z + (NumSelections * NumSelections)/100 + (2*(rand()/RAND_MAX) -1);
a = Round(z);
}
}
//Check to see if the engine has enough energy to hit the target
//This compares the distance between the two points
if( (Energy * dist) < (dist) || (active == false)) //if there isn''t enough return false or there was no spark
{
return false;
}
else
{
return true;
}
//Its wierd, im writing this durring a thunder storm...hope it doesn''t fry
//the computer befroe i do
}
Need pointer help with my lightning tutorial
Im writing a lightning tutorial for NeHe and im having trouble implementing a singly linked list and a bit of pointer manipulation. Here''s the code:
The problem occurs in the update function. I think it''s happening in the first while loop. When i run the program in debug mode i get this error:
Debug Assertion Failed!
...
File:dbgdel.cpp
Line:47
Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
...
and in release mode i get an illegal operation. Im basically trying to make lightning bolt out of a fractal tree, and the tree is continously built until the energy in the bolt runs out resulting in no more current sections. Does anyone know what is causing this and if so any possible ways to fix this problem?
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement