225 lines
4.7 KiB
C++
225 lines
4.7 KiB
C++
/* This software is the propery of 'SaraCraft' - developed by Allanis.
|
|
* Only members directly assosiated with the SaraCraft project may view/change
|
|
* this code.
|
|
*/
|
|
|
|
#ifdef WIN32
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
#include <iostream>
|
|
#include <GL/gl.h>
|
|
#include <vector>
|
|
#include <list>
|
|
#include <time.h>
|
|
#include <stdlib.h>
|
|
#include "Log.h"
|
|
#include "image.h"
|
|
#include "Point.h"
|
|
#include "Terrain.h"
|
|
#include "BoundBox.h"
|
|
#include "Wave.h"
|
|
#include "WaveEmitter.h"
|
|
|
|
using namespace std;
|
|
|
|
#define WAVE_RATE .002
|
|
#define EMIT_RATE 3300
|
|
#define EMIT_DIFF_PERCENT .2
|
|
#define EMIT_RATIO .2
|
|
|
|
class WaveLoc {
|
|
public:
|
|
float x;
|
|
float z;
|
|
float angle;
|
|
};
|
|
|
|
GLuint WaveEmitter::waveList = 0;
|
|
list <Wave*> WaveEmitter::activeWaves;
|
|
|
|
WaveEmitter::WaveEmitter(Terrain *terrain, BoundBox *box) {
|
|
// List of points on shore
|
|
list< Point* > shorePoints;
|
|
Point *temp;
|
|
float tAngle = 0.0;
|
|
WaveLoc *tLoc;
|
|
|
|
ticksToNextEmit = (int) (EMIT_RATE*(rand()/(RAND_MAX+1.0)));
|
|
|
|
//counter = 0.0;
|
|
|
|
isVisible = false;
|
|
|
|
// Populate the shore line list
|
|
terrain->locateShoreLine(box, &shorePoints);
|
|
|
|
while(!shorePoints.empty()) {
|
|
// First, we need to read the front element of the list
|
|
temp = shorePoints.front();
|
|
// Next, remove the shore element
|
|
shorePoints.pop_front();
|
|
|
|
// Find shore angle and move point to propper distance
|
|
if(terrain->findNearestShoreAngle(temp, &tAngle)) {
|
|
// Set tLoc angle and move point to propper distance
|
|
tLoc = new WaveLoc();
|
|
tLoc->x = temp->x;
|
|
tLoc->z = temp->z;
|
|
tLoc->angle = tAngle;
|
|
waveLocations.push_back(tLoc);
|
|
}
|
|
|
|
// Finaly delete the Point the list element pointed to
|
|
delete temp;
|
|
}
|
|
}
|
|
|
|
WaveEmitter::~WaveEmitter() {
|
|
// Delete the wave locations in vector
|
|
WaveLoc *temp;
|
|
while(!waveLocations.empty()) {
|
|
temp = waveLocations.back();
|
|
waveLocations.pop_back();
|
|
delete temp;
|
|
}
|
|
}
|
|
|
|
void WaveEmitter::update(unsigned int ticks) {
|
|
int numToGenerate;
|
|
|
|
ticksToNextEmit -= ticks;
|
|
|
|
if(ticksToNextEmit <= 0) {
|
|
// Update ticksToNextEmit
|
|
// I add EMIT_RATE and ticksToNextEmit so that it keeps the emit rate exact (I hope)
|
|
ticksToNextEmit = getNextEmit() + ticksToNextEmit;
|
|
|
|
// Add a new wave (only if it is visible???)
|
|
if(isVisible) {
|
|
numToGenerate = 1+(int) (waveLocations.size() * EMIT_RATIO * (rand()/(RAND_MAX+1.0)));
|
|
for(int i = 0; i < numToGenerate; i++) {
|
|
generateWave();
|
|
}
|
|
}
|
|
}
|
|
|
|
isVisible = false;
|
|
}
|
|
|
|
void WaveEmitter::setVisible() {
|
|
isVisible = true;
|
|
}
|
|
|
|
int WaveEmitter::getNextEmit() {
|
|
int diff = (int) (EMIT_DIFF_PERCENT * EMIT_RATE);
|
|
float randNum = (2.0 * (rand() / (RAND_MAX + 1.0))) - 1;
|
|
|
|
return EMIT_RATE + (int) (diff * randNum);
|
|
}
|
|
|
|
void WaveEmitter::generateWaveList() {
|
|
// Generate the surf list
|
|
waveList = glGenLists(1);
|
|
if(waveList == 0) {
|
|
// Should throw an exception
|
|
return;
|
|
}
|
|
|
|
glNewList(waveList, GL_COMPILE);
|
|
|
|
// Draw the actual surf
|
|
glBegin(GL_QUADS);
|
|
glTexCoord2f(0, 1);
|
|
glVertex3f(1, 0, -.3);
|
|
glTexCoord2f(1, 1);
|
|
glVertex3f(-1, 0, -.3);
|
|
glTexCoord2f(1, 0);
|
|
glVertex3f(-1, 0, .3);
|
|
glTexCoord2f(0, 0);
|
|
glVertex3f(1, 0, .3);
|
|
glEnd();
|
|
|
|
glEndList();
|
|
}
|
|
|
|
void WaveEmitter::deleteWaveList() {
|
|
glDeleteLists(waveList, 1);
|
|
}
|
|
|
|
void WaveEmitter::generateWave() {
|
|
WaveLoc *temp;
|
|
int index;
|
|
|
|
index = (int) (waveLocations.size() * (rand() / (RAND_MAX + 1.0)));
|
|
|
|
temp = waveLocations[index];
|
|
|
|
activeWaves.push_back(new Wave(temp->x, temp->z, temp->angle));
|
|
}
|
|
|
|
int WaveEmitter::numWaveLocations() {
|
|
return waveLocations.size();
|
|
}
|
|
|
|
void WaveEmitter::drawActiveWaves() {
|
|
Wave *temp;
|
|
list< Wave* >::iterator iter;
|
|
list< Wave* >::iterator listEnd;
|
|
|
|
if(activeWaves.size() <= 0) return;
|
|
|
|
glEnable(GL_COLOR_MATERIAL);
|
|
// Disable depth writes
|
|
glDepthMask(GL_FALSE);
|
|
|
|
iter = activeWaves.begin();
|
|
listEnd = activeWaves.end();
|
|
while(iter != listEnd) {
|
|
temp = *iter;
|
|
glPushMatrix();
|
|
temp->prepDraw();
|
|
glCallList(waveList);
|
|
glPopMatrix();
|
|
|
|
++iter;
|
|
}
|
|
|
|
// Reenable depth testing
|
|
glDepthMask(GL_TRUE);
|
|
glDisable(GL_COLOR_MATERIAL);
|
|
}
|
|
|
|
void WaveEmitter::updateActiveWaves(unsigned int ticks) {
|
|
Wave *temp;
|
|
list< Wave* >::iterator iter;
|
|
list< Wave* >::iterator listEnd;
|
|
|
|
if(activeWaves.size() <= 0) return;
|
|
|
|
temp = activeWaves.front();
|
|
while(!activeWaves.empty() && !temp->isActive()) {
|
|
activeWaves.pop_front();
|
|
}
|
|
|
|
iter = activeWaves.begin();
|
|
listEnd = activeWaves.end();
|
|
while(iter != listEnd) {
|
|
temp = *iter;
|
|
temp->update(ticks);
|
|
|
|
++iter;
|
|
}
|
|
}
|
|
|
|
void WaveEmitter::deleteActiveWaves() {
|
|
Wave *temp;
|
|
|
|
while(!activeWaves.empty()) {
|
|
temp = activeWaves.front();
|
|
activeWaves.pop_front();
|
|
delete temp;
|
|
}
|
|
}
|