mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-05 15:36:38 +00:00
Recast navigation
This commit is contained in:
@@ -0,0 +1,317 @@
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "SampleInterfaces.h"
|
||||
#include "Recast.h"
|
||||
#include "RecastDebugDraw.h"
|
||||
#include "DetourDebugDraw.h"
|
||||
#include "PerfTimer.h"
|
||||
#include "SDL.h"
|
||||
#include "SDL_opengl.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BuildContext::BuildContext() :
|
||||
m_messageCount(0),
|
||||
m_textPoolSize(0)
|
||||
{
|
||||
memset(m_messages, 0, sizeof(char*) * MAX_MESSAGES);
|
||||
|
||||
resetTimers();
|
||||
}
|
||||
|
||||
// Virtual functions for custom implementations.
|
||||
void BuildContext::doResetLog()
|
||||
{
|
||||
m_messageCount = 0;
|
||||
m_textPoolSize = 0;
|
||||
}
|
||||
|
||||
void BuildContext::doLog(const rcLogCategory category, const char* msg, const int len)
|
||||
{
|
||||
if (!len) return;
|
||||
if (m_messageCount >= MAX_MESSAGES)
|
||||
return;
|
||||
char* dst = &m_textPool[m_textPoolSize];
|
||||
int n = TEXT_POOL_SIZE - m_textPoolSize;
|
||||
if (n < 2)
|
||||
return;
|
||||
char* cat = dst;
|
||||
char* text = dst+1;
|
||||
const int maxtext = n-1;
|
||||
// Store category
|
||||
*cat = (char)category;
|
||||
// Store message
|
||||
const int count = rcMin(len+1, maxtext);
|
||||
memcpy(text, msg, count);
|
||||
text[count-1] = '\0';
|
||||
m_textPoolSize += 1 + count;
|
||||
m_messages[m_messageCount++] = dst;
|
||||
}
|
||||
|
||||
void BuildContext::doResetTimers()
|
||||
{
|
||||
for (int i = 0; i < RC_MAX_TIMERS; ++i)
|
||||
m_accTime[i] = -1;
|
||||
}
|
||||
|
||||
void BuildContext::doStartTimer(const rcTimerLabel label)
|
||||
{
|
||||
m_startTime[label] = getPerfTime();
|
||||
}
|
||||
|
||||
void BuildContext::doStopTimer(const rcTimerLabel label)
|
||||
{
|
||||
const TimeVal endTime = getPerfTime();
|
||||
const TimeVal deltaTime = endTime - m_startTime[label];
|
||||
if (m_accTime[label] == -1)
|
||||
m_accTime[label] = deltaTime;
|
||||
else
|
||||
m_accTime[label] += deltaTime;
|
||||
}
|
||||
|
||||
int BuildContext::doGetAccumulatedTime(const rcTimerLabel label) const
|
||||
{
|
||||
return getPerfTimeUsec(m_accTime[label]);
|
||||
}
|
||||
|
||||
void BuildContext::dumpLog(const char* format, ...)
|
||||
{
|
||||
// Print header.
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vprintf(format, ap);
|
||||
va_end(ap);
|
||||
printf("\n");
|
||||
|
||||
// Print messages
|
||||
const int TAB_STOPS[4] = { 28, 36, 44, 52 };
|
||||
for (int i = 0; i < m_messageCount; ++i)
|
||||
{
|
||||
const char* msg = m_messages[i]+1;
|
||||
int n = 0;
|
||||
while (*msg)
|
||||
{
|
||||
if (*msg == '\t')
|
||||
{
|
||||
int count = 1;
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
if (n < TAB_STOPS[j])
|
||||
{
|
||||
count = TAB_STOPS[j] - n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (--count)
|
||||
{
|
||||
putchar(' ');
|
||||
n++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
putchar(*msg);
|
||||
n++;
|
||||
}
|
||||
msg++;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
int BuildContext::getLogCount() const
|
||||
{
|
||||
return m_messageCount;
|
||||
}
|
||||
|
||||
const char* BuildContext::getLogText(const int i) const
|
||||
{
|
||||
return m_messages[i]+1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class GLCheckerTexture
|
||||
{
|
||||
unsigned int m_texId;
|
||||
public:
|
||||
GLCheckerTexture() : m_texId(0)
|
||||
{
|
||||
}
|
||||
|
||||
~GLCheckerTexture()
|
||||
{
|
||||
if (m_texId != 0)
|
||||
glDeleteTextures(1, &m_texId);
|
||||
}
|
||||
void bind()
|
||||
{
|
||||
if (m_texId == 0)
|
||||
{
|
||||
// Create checker pattern.
|
||||
const unsigned int col0 = duRGBA(215,215,215,255);
|
||||
const unsigned int col1 = duRGBA(255,255,255,255);
|
||||
static const int TSIZE = 64;
|
||||
unsigned int data[TSIZE*TSIZE];
|
||||
|
||||
glGenTextures(1, &m_texId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texId);
|
||||
|
||||
int level = 0;
|
||||
int size = TSIZE;
|
||||
while (size > 0)
|
||||
{
|
||||
for (int y = 0; y < size; ++y)
|
||||
for (int x = 0; x < size; ++x)
|
||||
data[x+y*size] = (x==0 || y==0) ? col0 : col1;
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size,size, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
size /= 2;
|
||||
level++;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, m_texId);
|
||||
}
|
||||
}
|
||||
};
|
||||
GLCheckerTexture g_tex;
|
||||
|
||||
|
||||
void DebugDrawGL::depthMask(bool state)
|
||||
{
|
||||
glDepthMask(state ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
void DebugDrawGL::texture(bool state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
g_tex.bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugDrawGL::begin(duDebugDrawPrimitives prim, float size)
|
||||
{
|
||||
switch (prim)
|
||||
{
|
||||
case DU_DRAW_POINTS:
|
||||
glPointSize(size);
|
||||
glBegin(GL_POINTS);
|
||||
break;
|
||||
case DU_DRAW_LINES:
|
||||
glLineWidth(size);
|
||||
glBegin(GL_LINES);
|
||||
break;
|
||||
case DU_DRAW_TRIS:
|
||||
glBegin(GL_TRIANGLES);
|
||||
break;
|
||||
case DU_DRAW_QUADS:
|
||||
glBegin(GL_QUADS);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
void DebugDrawGL::vertex(const float* pos, unsigned int color)
|
||||
{
|
||||
glColor4ubv((GLubyte*)&color);
|
||||
glVertex3fv(pos);
|
||||
}
|
||||
|
||||
void DebugDrawGL::vertex(const float x, const float y, const float z, unsigned int color)
|
||||
{
|
||||
glColor4ubv((GLubyte*)&color);
|
||||
glVertex3f(x,y,z);
|
||||
}
|
||||
|
||||
void DebugDrawGL::vertex(const float* pos, unsigned int color, const float* uv)
|
||||
{
|
||||
glColor4ubv((GLubyte*)&color);
|
||||
glTexCoord2fv(uv);
|
||||
glVertex3fv(pos);
|
||||
}
|
||||
|
||||
void DebugDrawGL::vertex(const float x, const float y, const float z, unsigned int color, const float u, const float v)
|
||||
{
|
||||
glColor4ubv((GLubyte*)&color);
|
||||
glTexCoord2f(u,v);
|
||||
glVertex3f(x,y,z);
|
||||
}
|
||||
|
||||
void DebugDrawGL::end()
|
||||
{
|
||||
glEnd();
|
||||
glLineWidth(1.0f);
|
||||
glPointSize(1.0f);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FileIO::FileIO() :
|
||||
m_fp(0),
|
||||
m_mode(-1)
|
||||
{
|
||||
}
|
||||
|
||||
FileIO::~FileIO()
|
||||
{
|
||||
if (m_fp) fclose(m_fp);
|
||||
}
|
||||
|
||||
bool FileIO::openForWrite(const char* path)
|
||||
{
|
||||
if (m_fp) return false;
|
||||
m_fp = fopen(path, "wb");
|
||||
if (!m_fp) return false;
|
||||
m_mode = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileIO::openForRead(const char* path)
|
||||
{
|
||||
if (m_fp) return false;
|
||||
m_fp = fopen(path, "rb");
|
||||
if (!m_fp) return false;
|
||||
m_mode = 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileIO::isWriting() const
|
||||
{
|
||||
return m_mode == 1;
|
||||
}
|
||||
|
||||
bool FileIO::isReading() const
|
||||
{
|
||||
return m_mode == 2;
|
||||
}
|
||||
|
||||
bool FileIO::write(const void* ptr, const size_t size)
|
||||
{
|
||||
if (!m_fp || m_mode != 1) return false;
|
||||
fwrite(ptr, size, 1, m_fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileIO::read(void* ptr, const size_t size)
|
||||
{
|
||||
if (!m_fp || m_mode != 2) return false;
|
||||
size_t readLen = fread(ptr, size, 1, m_fp);
|
||||
return readLen == 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user