initial commit
This commit is contained in:
39
engine/AABB.h
Normal file
39
engine/AABB.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef BLUECORE_BOUNDING_CUBE_H
|
||||
#define BLUECORE_BOUNDING_CUBE_H
|
||||
|
||||
#include "Math/Transformation.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
class AABB
|
||||
{
|
||||
|
||||
public:
|
||||
Vector3 Min;
|
||||
Vector3 Max;
|
||||
|
||||
bool overlaps (const AABB &aabb)
|
||||
{
|
||||
bool overlap = true;
|
||||
|
||||
overlap = (Min.x > aabb.Max.x || Max.x < aabb.Min.x) ? false : overlap;
|
||||
overlap = (Min.y > aabb.Max.y || Max.y < aabb.Min.y) ? false : overlap;
|
||||
overlap = (Min.z > aabb.Max.z || Max.z < aabb.Min.z) ? false : overlap;
|
||||
|
||||
return overlap;
|
||||
}
|
||||
|
||||
AABB transformed (const Transformation& transformation)
|
||||
{
|
||||
AABB aabb;
|
||||
|
||||
Vector3 new_max = transformation.transform (Max);
|
||||
Vector3 new_min = transformation.transform (Min);
|
||||
|
||||
return aabb;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
123
engine/Camera.cpp
Normal file
123
engine/Camera.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
#include "Camera.h"
|
||||
|
||||
#include "Math/Matrix.h"
|
||||
|
||||
#include "GL/glfw.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
Camera::Camera()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
Camera::~Camera()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Camera::setFoV(Scalar fov)
|
||||
{
|
||||
_FoV = fov;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Camera::setAspectRatio(Scalar aspect)
|
||||
{
|
||||
_AspectRatio = aspect;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Camera::setNearPlane(Scalar near)
|
||||
{
|
||||
_NearPlane = near;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Camera::setFarPlane(Scalar far)
|
||||
{
|
||||
_FarPlane = far;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Camera::setPosition(const Vector3& position)
|
||||
{
|
||||
_Position = position;
|
||||
}
|
||||
|
||||
const Vector3& Camera::getPosition()
|
||||
{
|
||||
return _Position;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Camera::setRotation(const Quaternion& rotation)
|
||||
{
|
||||
_Rotation = rotation;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Camera::setupProjectionMatrix()
|
||||
{
|
||||
Scalar fW, fH;
|
||||
|
||||
fH = tan ( (_FoV / 2) / 180* Pi ) * _NearPlane;
|
||||
fW = fH * _AspectRatio;
|
||||
|
||||
// setup projectiom matrix
|
||||
glMatrixMode (GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glFrustum ( -fW, fW, -fH, fH, _NearPlane, _FarPlane );
|
||||
|
||||
// save variables for frustum culling
|
||||
/*
|
||||
_near = nearZ;
|
||||
_far = farZ;
|
||||
_hNear = tan ( ( fov / 2 ) / 180 * Pi ) * nearZ;
|
||||
_wNear = _hNear * aspect;
|
||||
_hFar = tan ( ( fov / 2 ) / 180 * Pi ) * farZ;
|
||||
_wFar = _hFar * aspect;
|
||||
*/
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Camera::setupViewMatrix()
|
||||
{
|
||||
// set the view matrix
|
||||
glMatrixMode (GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
Matrix4x4 m(_Rotation, _Rotation.applyInversed(_Position * -1.0) );
|
||||
glMultMatrixd ( ( GLdouble * ) &m.m );
|
||||
/*
|
||||
// calculate frustum planes
|
||||
Vector3 up = q.apply ( Vector3 ( 0.0, 1.0, 0.0 ) );
|
||||
Vector3 right = q.apply ( Vector3 ( 1.0, 0.0, 0.0 ) );
|
||||
Vector3 d = q.apply ( Vector3 ( 0.0, 0.0, -1.0 ) );
|
||||
|
||||
Vector3 fc = p + d * _far;
|
||||
|
||||
Vector3 ftl = fc + ( up * _hFar ) - ( right * _wFar );
|
||||
Vector3 ftr = fc + ( up * _hFar ) + ( right * _wFar );
|
||||
Vector3 fbl = fc - ( up * _hFar ) - ( right * _wFar );
|
||||
Vector3 fbr = fc - ( up * _hFar ) + ( right * _wFar );
|
||||
|
||||
Vector3 nc = p + d * _near;
|
||||
|
||||
Vector3 ntl = nc + ( up * _hNear ) - ( right * _wNear );
|
||||
Vector3 ntr = nc + ( up * _hNear ) + ( right * _wNear );
|
||||
Vector3 nbl = nc - ( up * _hNear ) - ( right * _wNear );
|
||||
Vector3 nbr = nc - ( up * _hNear ) + ( right * _wNear );
|
||||
|
||||
_frustumPlanes[RightPlane] = Plane ( nbr, fbr, ntr );
|
||||
_frustumPlanes[LeftPlane] = Plane ( ntl, fbl, nbl );
|
||||
_frustumPlanes[BottomPlane] = Plane ( nbl, fbr, nbr );
|
||||
_frustumPlanes[TopPlane] = Plane ( ntr, ftl, ntl );
|
||||
_frustumPlanes[FarPlane] = Plane ( ftl, ftr, fbl );
|
||||
_frustumPlanes[NearPlane] = Plane ( ntl, nbl, ntr );
|
||||
*/
|
||||
}
|
||||
|
||||
} // namespace BlueCore
|
||||
|
55
engine/Camera.h
Normal file
55
engine/Camera.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef BLUECORE_CAMERA_H
|
||||
#define BLUECORE_CAMERA_H
|
||||
|
||||
// project includes
|
||||
#include "Utilities/Referenced.h"
|
||||
#include "Math/Vector.h"
|
||||
#include "Math/Quaternion.h"
|
||||
#include "Math/Plane.h"
|
||||
//#include "geometry/frustum.h"
|
||||
|
||||
namespace BlueCore {
|
||||
|
||||
class Camera : public Referenced
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
Vector3 _LookAtPoint;
|
||||
Vector3 _LookAtUp;
|
||||
bool _LookAt;
|
||||
Scalar _NearPlane, _FarPlane, _FoV, _AspectRatio;
|
||||
//Frustum _Frustum;
|
||||
|
||||
Vector3 _Position;
|
||||
Quaternion _Rotation;
|
||||
|
||||
public:
|
||||
|
||||
Camera();
|
||||
~Camera();
|
||||
|
||||
void lookAt( const Vector3 &point );
|
||||
void lookAt( const Vector3 &point, const Vector3 &up );
|
||||
void lookStraight();
|
||||
|
||||
void setFoV( Scalar fov );
|
||||
void setAspectRatio( Scalar aspect );
|
||||
void setNearPlane( Scalar near );
|
||||
void setFarPlane( Scalar far );
|
||||
|
||||
void setPosition (const Vector3& position);
|
||||
const Vector3& getPosition ();
|
||||
|
||||
void setRotation (const Quaternion& rotation);
|
||||
|
||||
void setupViewMatrix ();
|
||||
void setupProjectionMatrix ();
|
||||
|
||||
//const Frustum &getFrustum() const;
|
||||
};
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif
|
||||
|
57
engine/FileSystem.h
Normal file
57
engine/FileSystem.h
Normal file
@ -0,0 +1,57 @@
|
||||
#include "Utilities/Referenced.h"
|
||||
|
||||
|
||||
class File : public Referenced
|
||||
{
|
||||
public:
|
||||
bool isOpen ();
|
||||
unsigned long read (char *buffer, unsigned long size);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class FileSystem : public Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
FileSystem();
|
||||
File *openBinary (const std::string& filename);
|
||||
|
||||
private:
|
||||
|
||||
static bool _PhysfsInialized;
|
||||
};
|
||||
|
||||
|
||||
|
||||
FileSystem::FileSystem()
|
||||
{
|
||||
PHYSFS_init (0);
|
||||
|
||||
std::string appdir = PHYSFS_getUserDir();
|
||||
appdir += ".bluecore";
|
||||
|
||||
if( !PHYSFS_setWriteDir(appdir.c_str()) )
|
||||
{
|
||||
if( (PHYSFS_setWriteDir(PHYSFS_getUserDir())) && (PHYSFS_mkdir(".bluecore")) )
|
||||
PHYSFS_setWriteDir( appdir.c_str() );
|
||||
}
|
||||
|
||||
PHYSFS_addToSearchPath( appdir.c_str(), 0 );
|
||||
PHYSFS_addToSearchPath( "data", 1 );
|
||||
|
||||
char **rc = PHYSFS_enumerateFiles ( "" );
|
||||
|
||||
for ( char **i = rc; *i != 0; i++ )
|
||||
{
|
||||
std::string filename ( *i );
|
||||
|
||||
if ( filename.substr ( filename.size() - 4, 4 ) == ".zip" )
|
||||
{
|
||||
PHYSFS_addToSearchPath ( ( "data/" + filename ).c_str(), 1 );
|
||||
BlueCore::log << ">>> Using addon: " << filename << endlog;
|
||||
}
|
||||
}
|
||||
|
||||
PHYSFS_freeList ( rc );
|
||||
}
|
204
engine/FontManager.cpp
Normal file
204
engine/FontManager.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
#include "FontManager.h"
|
||||
#include "RenderDevice.h"
|
||||
|
||||
// project includes
|
||||
#include "Utilities/Buffer.h"
|
||||
#include "Utilities/Log.h"
|
||||
#include "Utilities/format.h"
|
||||
|
||||
// library includes
|
||||
#include "physfs.h"
|
||||
#include "FTGLTextureFont.h"
|
||||
|
||||
// system includes
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "FontManagerDefaultFont.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
FontManager::FontManager(RenderDevice* device) :
|
||||
_Device(device)
|
||||
{
|
||||
// create default font
|
||||
FTFont *ftfont = new FTGLTextureFont (
|
||||
DefaultFontBytes,
|
||||
sizeof ( DefaultFontBytes ),
|
||||
false );
|
||||
ftfont->FaceSize( 16);
|
||||
_DefaultFont = new Font( ftfont, 0, device );
|
||||
|
||||
if (_Device.valid())
|
||||
_Device->DeviceShutdownSignal.connect(this,
|
||||
&FontManager::DeviceShutdownSlot);
|
||||
|
||||
clog << ">>> FontManager constructed..."<< endline;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
FontManager::~FontManager()
|
||||
{
|
||||
destroy();
|
||||
|
||||
clog << ">>> FontManager destructed..."<< endline;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void FontManager::DeviceShutdownSlot()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void FontManager::destroy()
|
||||
{
|
||||
FontMap::iterator i;
|
||||
|
||||
for (i = _fonts.begin(); i != _fonts.end(); i++)
|
||||
{
|
||||
if (i->second.valid())
|
||||
i->second->destroy();
|
||||
}
|
||||
|
||||
_DefaultFont = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Font *FontManager::loadFont(const std::string &filename, int size, bool hinting)
|
||||
{
|
||||
string key = format("%s-%d", filename.c_str(), size);
|
||||
|
||||
// check if this font is already loaded
|
||||
FontMap::const_iterator result;
|
||||
result = _fonts.find(key);
|
||||
|
||||
if (result != _fonts.end() && result->second.valid())
|
||||
{
|
||||
return result->second.get();
|
||||
}
|
||||
|
||||
Font *font;
|
||||
|
||||
PHYSFS_file *file = PHYSFS_openRead(filename.c_str() );
|
||||
|
||||
if (file)
|
||||
{
|
||||
unsigned int file_size = PHYSFS_fileLength(file);
|
||||
unsigned char *buffer = new unsigned char[file_size];
|
||||
|
||||
PHYSFS_read(file, buffer, 1, file_size);
|
||||
PHYSFS_close(file);
|
||||
|
||||
// create the font
|
||||
FTFont *ftfont = new FTGLTextureFont ( buffer, file_size, hinting );
|
||||
ftfont->FaceSize(size);
|
||||
|
||||
if (ftfont->Error() == 0)
|
||||
{
|
||||
font = new Font( ftfont, buffer, _Device.get() );
|
||||
clog << ">>> Font '"<< filename << "' ("<< size << ") loaded"
|
||||
<< endline;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete ftfont;
|
||||
clog << "!!! Font '"<< filename << "' could not be loaded"
|
||||
<< endline;
|
||||
font = new Font();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clog << "!!! Font '"<< filename << "' not found"<< endline;
|
||||
font = new Font();
|
||||
}
|
||||
|
||||
_fonts[key] = font;
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Font *FontManager::getDefaultFont()
|
||||
{
|
||||
return _DefaultFont.get();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Font::Font()
|
||||
{
|
||||
_Font = 0;
|
||||
_Buffer = 0;
|
||||
clog << ">>> Font constructed..."<< endline;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Font::Font(FTFont *font, unsigned char *buffer, RenderDevice* device) :
|
||||
_Font(font), _Buffer(buffer), _Device(device)
|
||||
{
|
||||
clog << ">>> Font constructed..."<< endline;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Font::~Font()
|
||||
{
|
||||
destroy();
|
||||
clog << ">>> Font destructed..."<< endline;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Font::destroy()
|
||||
{
|
||||
delete _Font;
|
||||
delete [] _Buffer;
|
||||
clog << ">>> Font destroyed..."<< endline;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Font::print(float x, float y, const std::string &text, int halign,
|
||||
int valign) const
|
||||
{
|
||||
if (_Font == 0)
|
||||
return;
|
||||
|
||||
if (_Device.valid() == false)
|
||||
return;
|
||||
|
||||
_Device->begin2D();
|
||||
|
||||
if (x < 0.0)
|
||||
x += _Device->getViewportWidth();
|
||||
else if (x <= 1.0)
|
||||
x *= _Device->getViewportWidth();
|
||||
|
||||
if (halign == 0)
|
||||
x -= _Font->Advance(text.c_str() ) / 2;
|
||||
else if (halign == -1)
|
||||
x -= _Font->Advance(text.c_str() );
|
||||
|
||||
if (y < 0.0)
|
||||
y += _Device->getViewportHeight();
|
||||
else if (y <= 1.0)
|
||||
y *= _Device->getViewportHeight();
|
||||
|
||||
y -= _Font->Descender();
|
||||
if (valign == 0)
|
||||
y -= _Font->LineHeight() / 2;
|
||||
else if (valign == -1)
|
||||
y -= _Font->LineHeight();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glTranslatef(x, y, 0);
|
||||
_Font->Render(text.c_str() );
|
||||
glPopMatrix();
|
||||
|
||||
_Device->end2D();
|
||||
}
|
||||
|
||||
} // namespace BlueCore
|
70
engine/FontManager.h
Normal file
70
engine/FontManager.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef BLUECORE_FONT_MANAGER_H
|
||||
#define BLUECORE_FONT_MANAGER_H
|
||||
|
||||
// system includes
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
// project includes
|
||||
#include "Utilities/Referenced.h"
|
||||
|
||||
#include "RenderDevice.h"
|
||||
|
||||
// forward declaratins
|
||||
class FTFont;
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
class Font : public Referenced
|
||||
{
|
||||
FTFont *_Font;
|
||||
unsigned char *_Buffer;
|
||||
ref_ptr<RenderDevice> _Device;
|
||||
|
||||
protected:
|
||||
|
||||
~Font();
|
||||
|
||||
public:
|
||||
|
||||
Font(FTFont *font, unsigned char *buffer, RenderDevice *device);
|
||||
Font();
|
||||
|
||||
void destroy();
|
||||
|
||||
void print(float x, float y, const std::string &text, int halign = 0,
|
||||
int valign = 0) const;
|
||||
};
|
||||
|
||||
class FontManager : public Referenced, public sigslot::has_slots<>
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef std::map<std::string, weak_ptr<Font> > FontMap;
|
||||
|
||||
FontMap _fonts;
|
||||
ref_ptr<Font> _DefaultFont;
|
||||
|
||||
void FontDestroyedSlot(Referenced*);
|
||||
|
||||
void DeviceShutdownSlot();
|
||||
|
||||
void destroy();
|
||||
|
||||
public:
|
||||
|
||||
FontManager(RenderDevice* device);
|
||||
~FontManager();
|
||||
|
||||
Font *loadFont(const std::string &name, int size, bool hinting = true);
|
||||
Font *getDefaultFont();
|
||||
|
||||
private:
|
||||
|
||||
ref_ptr<RenderDevice> _Device;
|
||||
};
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif // BLUECORE_FONT_MANAGER_H
|
4483
engine/FontManagerDefaultFont.h
Normal file
4483
engine/FontManagerDefaultFont.h
Normal file
File diff suppressed because it is too large
Load Diff
66
engine/Makefile
Normal file
66
engine/Makefile
Normal file
@ -0,0 +1,66 @@
|
||||
include ../Makefile.common
|
||||
|
||||
CXXFLAGS += -I../glfw/include
|
||||
LDFLAGS += -L../glfw -lglfw
|
||||
|
||||
CXXFLAGS += -I../trimeshloader/include
|
||||
LDFLAGS += -L../trimeshloader -ltrimeshloader
|
||||
|
||||
CXXFLAGS += -I../physfs
|
||||
LDFLAGS += -L../physfs -lphysfs
|
||||
|
||||
CXXFLAGS += -I../ftgl
|
||||
LDFLAGS += -L../ftgl -lftgl
|
||||
|
||||
CXXFLAGS += -I../freetype/include
|
||||
LDFLAGS += -L../freetype -lfreetype
|
||||
|
||||
CXXFLAGS += -I../corona/src
|
||||
LDFLAGS += -L../corona -lcorona
|
||||
|
||||
CXXFLAGS += -I../glew/include
|
||||
LDFLAGS += -L../glew -lglew
|
||||
|
||||
CXXFLAGS += -I../squirrel/include
|
||||
LDFLAGS += -L../squirrel -lsquirrel
|
||||
|
||||
CXXFLAGS += -I../ode/include
|
||||
LDFLAGS += -L../ode -lode
|
||||
|
||||
CXXFLAGS += -I../tinyxml
|
||||
LDFLAGS += -L../tinyxml -ltinyxml
|
||||
|
||||
CXXFLAGS += -I../libpng
|
||||
LDFLAGS += -L../libpng -lpng
|
||||
|
||||
LDFLAGS += -L../zlib -lz
|
||||
|
||||
ifeq ($(OS),WIN32)
|
||||
LDFLAGS += -lglu32 -lwinmm -lole32 -lws2_32 -lopengl32
|
||||
else
|
||||
LDFLAGS += -lm -lGL -lGLU -lX11 -lXxf86vm -lXext #-lopenal -Wl,-rpath=. -L/usr/X11R6/lib
|
||||
endif
|
||||
|
||||
SRC = $(wildcard */*.cpp) $(wildcard *.cpp)
|
||||
OBJ = $(patsubst %.cpp,%.o,$(SRC) )
|
||||
DEP = $(patsubst %.cpp,%.d,$(SRC) )
|
||||
|
||||
NAME = redcore$(EXT)
|
||||
|
||||
all: $(NAME)
|
||||
|
||||
$(NAME): $(OBJ)
|
||||
@echo Linking $@...
|
||||
@g++ -o $(NAME) $(OBJ) $(LDFLAGS)
|
||||
@echo done
|
||||
|
||||
clean:
|
||||
-@$(RMSUB) *.o
|
||||
-@$(RMSUB) *.d
|
||||
-@$(RMSUB) Utilities$(SLASH)*.o
|
||||
-@$(RMSUB) Utilities$(SLASH)*.d
|
||||
-@$(RMSUB) Math$(SLASH)*.o
|
||||
-@$(RMSUB) Math$(SLASH)*.d
|
||||
-@$(RM) $(NAME)
|
||||
|
||||
-include $(SRC:%.cpp=%.d)
|
866
engine/Math/Matrix.h
Normal file
866
engine/Math/Matrix.h
Normal file
@ -0,0 +1,866 @@
|
||||
#ifndef BLUECORE_MATRIX_H
|
||||
#define BLUECORE_MATRIX_H
|
||||
|
||||
// system includes
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
// local includes
|
||||
#include "Scalar.h"
|
||||
#include "Vector.h"
|
||||
#include "Quaternion.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
template <class T>
|
||||
class Matrix3x3Template
|
||||
{
|
||||
public:
|
||||
T m[9];
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
inline Matrix3x3Template()
|
||||
{
|
||||
identity();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* constructor from array
|
||||
*/
|
||||
template <class S>
|
||||
inline Matrix3x3Template( const S a[9] )
|
||||
{
|
||||
m[0] = static_cast<T>(a[0]);
|
||||
m[1] = static_cast<T>(a[1]);
|
||||
m[2] = static_cast<T>(a[2]);
|
||||
|
||||
m[3] = static_cast<T>(a[3]);
|
||||
m[4] = static_cast<T>(a[4]);
|
||||
m[5] = static_cast<T>(a[5]);
|
||||
|
||||
m[6] = static_cast<T>(a[6]);
|
||||
m[7] = static_cast<T>(a[7]);
|
||||
m[8] = static_cast<T>(a[8]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* copy constructor
|
||||
*/
|
||||
template <class S>
|
||||
inline Matrix3x3Template( const Matrix3x3Template<S> &a )
|
||||
{
|
||||
m[0] = static_cast<T>(a.m[0]);
|
||||
m[1] = static_cast<T>(a.m[1]);
|
||||
m[2] = static_cast<T>(a.m[2]);
|
||||
|
||||
m[3] = static_cast<T>(a.m[3]);
|
||||
m[4] = static_cast<T>(a.m[4]);
|
||||
m[5] = static_cast<T>(a.m[5]);
|
||||
|
||||
m[6] = static_cast<T>(a.m[6]);
|
||||
m[7] = static_cast<T>(a.m[7]);
|
||||
m[8] = static_cast<T>(a.m[8]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* constructor from heading and up vectors
|
||||
*/
|
||||
inline Matrix3x3Template(
|
||||
const Vector3Template<T> &h,
|
||||
const Vector3Template<T> &u )
|
||||
{
|
||||
Vector3Template<T> a, b, c;
|
||||
c = h.unit();
|
||||
a = h.crossProduct( u ).unit();
|
||||
b = c.crossProduct( a ).unit();
|
||||
|
||||
m[0] = a.x;
|
||||
m[1] = b.x;
|
||||
m[2] = c.x;
|
||||
|
||||
m[3] = a.y;
|
||||
m[4] = b.y;
|
||||
m[5] = c.y;
|
||||
|
||||
m[6] = a.z;
|
||||
m[7] = b.z;
|
||||
m[8] = c.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* contructor from euler angles
|
||||
*/
|
||||
inline Matrix3x3Template( T a, T e, T t )
|
||||
{
|
||||
T ch = cos( a );
|
||||
T sh = sin( a );
|
||||
T ca = cos( e );
|
||||
T sa = sin( e );
|
||||
T cb = cos( t );
|
||||
T sb = sin( t );
|
||||
|
||||
m[0] = ch * ca;
|
||||
m[1] = sh*sb - ch*sa*cb;
|
||||
m[2] = ch*sa*sb + sh*cb;
|
||||
|
||||
m[3] = sa;
|
||||
m[4] = ca*cb;
|
||||
m[5] = -ca*sb;
|
||||
|
||||
m[6] = -sh*ca;
|
||||
m[7] = sh*sa*cb + ch*sb;
|
||||
m[8] = -sh*sa*sb + ch*cb;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* contructor from quaternion
|
||||
*/
|
||||
template <class S>
|
||||
inline Matrix3x3Template( const QuaternionTemplate<S> &q )
|
||||
{
|
||||
T xx = static_cast<T>(q.x*q.x),
|
||||
xy = static_cast<T>(q.x*q.y),
|
||||
xz = static_cast<T>(q.x*q.z),
|
||||
xw = static_cast<T>(q.x*q.w),
|
||||
|
||||
yy = static_cast<T>(q.y*q.y),
|
||||
yz = static_cast<T>(q.y*q.z),
|
||||
yw = static_cast<T>(q.y*q.w),
|
||||
|
||||
zz = static_cast<T>(q.z*q.z),
|
||||
zw = static_cast<T>(q.z*q.w);
|
||||
|
||||
m[0] = 1 - yy - yy - zz - zz;
|
||||
m[1] = xy + xy + zw + zw;
|
||||
m[2] = xz + xz - yw - yw;
|
||||
|
||||
m[3] = xy + xy - zw - zw;
|
||||
m[4] = 1 - xx - xx - zz - zz;
|
||||
m[5] = yz + yz + xw + xw;
|
||||
|
||||
m[6] = xz + xz + yw + yw;
|
||||
m[7] = yz + yz - xw - xw;
|
||||
m[8] = 1 - xx - xx - yy - yy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set matrix to identity matrix
|
||||
*/
|
||||
inline void identity()
|
||||
{
|
||||
m[0] = static_cast<T>(1);
|
||||
m[1] = static_cast<T>(0);
|
||||
m[2] = static_cast<T>(0);
|
||||
|
||||
m[3] = static_cast<T>(0);
|
||||
m[4] = static_cast<T>(1);
|
||||
m[5] = static_cast<T>(0);
|
||||
|
||||
m[6] = static_cast<T>(0);
|
||||
m[7] = static_cast<T>(0);
|
||||
m[8] = static_cast<T>(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get transposed matrix
|
||||
*/
|
||||
inline Matrix3x3Template<T> transposed() const
|
||||
{
|
||||
Matrix3x3Template<T> a;
|
||||
|
||||
a.m[0] = m[0]; a.m[3] = m[1]; a.m[6] = m[2];
|
||||
a.m[1] = m[3]; a.m[4] = m[4]; a.m[7] = m[5];
|
||||
a.m[2] = m[6]; a.m[5] = m[7]; a.m[8] = m[8];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* transpose
|
||||
*/
|
||||
inline void transpose()
|
||||
{
|
||||
swap( m[3], m[1] );
|
||||
swap( m[6], m[2] );
|
||||
swap( m[7], m[5] );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* determinate
|
||||
*/
|
||||
inline T determinant() const
|
||||
{
|
||||
return ( m[0]*m[4]*m[8] + m[1]*m[5]*m[6] + m[2]*m[3]*m[7] )
|
||||
- ( m[6]*m[4]*m[2] + m[7]*m[5]*m[0] + m[8]*m[3]*m[1] );
|
||||
}
|
||||
|
||||
inline Matrix3x3Template<T> inverted()
|
||||
{
|
||||
T det = determinant();
|
||||
T one_over_det = 1.0f / det;
|
||||
|
||||
Matrix3x3Template<T> result;
|
||||
result.m[0] = +(m[4] * m[8] - m[5] * m[7]) * one_over_det;
|
||||
result.m[1] = -(m[1] * m[8] - m[2] * m[7]) * one_over_det;
|
||||
result.m[2] = +(m[1] * m[5] - m[2] * m[4]) * one_over_det;
|
||||
result.m[3] = -(m[3] * m[8] - m[5] * m[6]) * one_over_det;
|
||||
result.m[4] = +(m[0] * m[8] - m[2] * m[6]) * one_over_det;
|
||||
result.m[5] = -(m[0] * m[5] - m[2] * m[3]) * one_over_det;
|
||||
result.m[6] = +(m[3] * m[7] - m[4] * m[6]) * one_over_det;
|
||||
result.m[7] = -(m[0] * m[7] - m[1] * m[6]) * one_over_det;
|
||||
result.m[8] = +(m[0] * m[4] - m[1] * m[3]) * one_over_det;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* add/assign operator
|
||||
*/
|
||||
template <class S>
|
||||
inline Matrix3x3Template<T> &operator += (
|
||||
const Matrix3x3Template<S> &a )
|
||||
{
|
||||
m[0] += static_cast<T>(a.m[0]);
|
||||
m[1] += static_cast<T>(a.m[1]);
|
||||
m[2] += static_cast<T>(a.m[2]);
|
||||
|
||||
m[3] += static_cast<T>(a.m[3]);
|
||||
m[4] += static_cast<T>(a.m[4]);
|
||||
m[5] += static_cast<T>(a.m[5]);
|
||||
|
||||
m[6] += static_cast<T>(a.m[6]);
|
||||
m[7] += static_cast<T>(a.m[7]);
|
||||
m[8] += static_cast<T>(a.m[8]);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* matrix multiplication
|
||||
*/
|
||||
template <class S>
|
||||
inline Matrix3x3Template<T> operator * ( const Matrix3x3Template<S> &a )
|
||||
{
|
||||
Matrix3x3Template<T> result;
|
||||
|
||||
result.m[0] = m[0] * static_cast<T>(a.m[0])
|
||||
+ m[3] * static_cast<T>(a.m[1])
|
||||
+ m[6] * static_cast<T>(a.m[2]);
|
||||
|
||||
result.m[1] = m[1] * static_cast<T>(a.m[0])
|
||||
+ m[4] * static_cast<T>(a.m[1])
|
||||
+ m[7] * static_cast<T>(a.m[2]);
|
||||
|
||||
result.m[2] = m[2] * static_cast<T>(a.m[0])
|
||||
+ m[5] * static_cast<T>(a.m[1])
|
||||
+ m[8] * static_cast<T>(a.m[2]);
|
||||
|
||||
|
||||
result.m[3] = m[0] * static_cast<T>(a.m[3])
|
||||
+ m[3] * static_cast<T>(a.m[4])
|
||||
+ m[6] * static_cast<T>(a.m[5]);
|
||||
|
||||
result.m[4] = m[1] * static_cast<T>(a.m[3])
|
||||
+ m[4] * static_cast<T>(a.m[4])
|
||||
+ m[7] * static_cast<T>(a.m[5]);
|
||||
|
||||
result.m[5] = m[2] * static_cast<T>(a.m[3])
|
||||
+ m[5] * static_cast<T>(a.m[4])
|
||||
+ m[8] * static_cast<T>(a.m[5]);
|
||||
|
||||
|
||||
result.m[6] = m[0] * static_cast<T>(a.m[6])
|
||||
+ m[3] * static_cast<T>(a.m[7])
|
||||
+ m[6] * static_cast<T>(a.m[8]);
|
||||
|
||||
result.m[7] = m[1] * static_cast<T>(a.m[6])
|
||||
+ m[4] * static_cast<T>(a.m[7])
|
||||
+ m[7] * static_cast<T>(a.m[8]);
|
||||
|
||||
result.m[8] = m[2] * static_cast<T>(a.m[6])
|
||||
+ m[5] * static_cast<T>(a.m[7])
|
||||
+ m[8] * static_cast<T>(a.m[8]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* matrix vector multiplication
|
||||
*/
|
||||
template <class S>
|
||||
Vector3Template<T> operator * ( const Vector3Template<S>& a )
|
||||
{
|
||||
return Vector3Template<T>(
|
||||
m[0] * static_cast<T>(a.x)
|
||||
+ m[3] * static_cast<T>(a.y)
|
||||
+ m[6] * static_cast<T>(a.z),
|
||||
m[1] * static_cast<T>(a.x)
|
||||
+ m[4] * static_cast<T>(a.y)
|
||||
+ m[7] * static_cast<T>(a.z),
|
||||
m[2] * static_cast<T>(a.x)
|
||||
+ m[5] * static_cast<T>(a.y)
|
||||
+ m[8] * static_cast<T>(a.z) );
|
||||
}
|
||||
|
||||
/**
|
||||
* matrix scalar multiplication
|
||||
*/
|
||||
template <class S>
|
||||
Matrix3x3Template<T> operator * ( const S a )
|
||||
{
|
||||
Matrix3x3Template<T> result;
|
||||
|
||||
result.m[0] = m[0] * static_cast<T>(a);
|
||||
result.m[1] = m[1] * static_cast<T>(a);
|
||||
result.m[2] = m[2] * static_cast<T>(a);
|
||||
result.m[3] = m[3] * static_cast<T>(a);
|
||||
result.m[4] = m[4] * static_cast<T>(a);
|
||||
result.m[5] = m[5] * static_cast<T>(a);
|
||||
result.m[6] = m[6] * static_cast<T>(a);
|
||||
result.m[7] = m[7] * static_cast<T>(a);
|
||||
result.m[8] = m[8] * static_cast<T>(a);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
friend std::ostream &operator << ( std::ostream& os, Matrix3x3Template<T> m )
|
||||
{
|
||||
os << "( " << m.m[0] << ", " << m.m[1] << ", " << m.m[2] << " )" << std::endl;
|
||||
os << "( " << m.m[3] << ", " << m.m[4] << ", " << m.m[5] << " )" << std::endl;
|
||||
os << "( " << m.m[6] << ", " << m.m[7] << ", " << m.m[8] << " )" << std::endl;
|
||||
return os;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef Matrix3x3Template<float> Matrix3x3Float;
|
||||
typedef Matrix3x3Template<double> Matrix3x3Double;
|
||||
typedef Matrix3x3Template<Scalar> Matrix3x3;
|
||||
|
||||
|
||||
template <class T>
|
||||
class Matrix4x4Template
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
T m[16];
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
inline Matrix4x4Template()
|
||||
{
|
||||
identity();
|
||||
}
|
||||
|
||||
inline void identity()
|
||||
{
|
||||
m[0] = static_cast<T>(1);
|
||||
m[1] = static_cast<T>(0);
|
||||
m[2] = static_cast<T>(0);
|
||||
m[3] = static_cast<T>(0);
|
||||
|
||||
m[4] = static_cast<T>(0);
|
||||
m[5] = static_cast<T>(1);
|
||||
m[6] = static_cast<T>(0);
|
||||
m[7] = static_cast<T>(0);
|
||||
|
||||
m[8] = static_cast<T>(0);
|
||||
m[9] = static_cast<T>(0);
|
||||
m[10] = static_cast<T>(1);
|
||||
m[11] = static_cast<T>(0);
|
||||
|
||||
m[12] = static_cast<T>(0);
|
||||
m[13] = static_cast<T>(0);
|
||||
m[14] = static_cast<T>(0);
|
||||
m[15] = static_cast<T>(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* constructor from array
|
||||
*/
|
||||
inline Matrix4x4Template( const T a[16] )
|
||||
{
|
||||
m[0] = a[0]; m[1] = a[1]; m[2] = a[2]; m[3] = a[3];
|
||||
m[4] = a[4]; m[5] = a[5]; m[6] = a[6]; m[7] = a[7];
|
||||
m[8] = a[8]; m[9] = a[9]; m[10] = a[10]; m[11] = a[11];
|
||||
m[12] = a[12]; m[13] = a[13]; m[14] = a[14]; m[15] = a[15];
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor from 3x3 matrix, add. element are set to zero
|
||||
*/
|
||||
inline Matrix4x4Template( const Matrix3x3Template<T> &a )
|
||||
{
|
||||
m[0] = a[0];
|
||||
m[1] = a[1];
|
||||
m[2] = a[2];
|
||||
m[3] = static_cast<T>(0);
|
||||
|
||||
m[4] = a[3];
|
||||
m[5] = a[4];
|
||||
m[6] = a[5];
|
||||
m[7] = static_cast<T>(0);
|
||||
|
||||
m[8] = a[6];
|
||||
m[9] = a[7];
|
||||
m[10] = a[8];
|
||||
m[11] = static_cast<T>(0);
|
||||
|
||||
m[12] = static_cast<T>(0);
|
||||
m[13] = static_cast<T>(0);
|
||||
m[14] = static_cast<T>(0);
|
||||
m[15] = static_cast<T>(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor from 3x3 rotation matrix and translation vector
|
||||
*/
|
||||
inline Matrix4x4Template(
|
||||
const Matrix3x3Template<T> &a,
|
||||
const Vector3Template<T> &b )
|
||||
{
|
||||
m[0] = a[0];
|
||||
m[1] = a[1];
|
||||
m[2] = a[2];
|
||||
m[3] = static_cast<T>(0);
|
||||
|
||||
m[4] = a[3];
|
||||
m[5] = a[4];
|
||||
m[6] = a[5];
|
||||
m[7] = static_cast<T>(0);
|
||||
|
||||
m[8] = a[6];
|
||||
m[9] = a[7];
|
||||
m[10] = a[8];
|
||||
m[11] = static_cast<T>(0);
|
||||
|
||||
m[12] = b.x;
|
||||
m[13] = b.y;
|
||||
m[14] = b.z;
|
||||
m[15] = static_cast<T>(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* copy constructor
|
||||
*/
|
||||
inline Matrix4x4Template( const Matrix4x4Template<T> &a )
|
||||
{
|
||||
m[0] = a.m[0];
|
||||
m[1] = a.m[1];
|
||||
m[2] = a.m[2];
|
||||
m[3] = a.m[3];
|
||||
|
||||
m[4] = a.m[4];
|
||||
m[5] = a.m[5];
|
||||
m[6] = a.m[6];
|
||||
m[7] = a.m[7];
|
||||
|
||||
m[8] = a.m[8];
|
||||
m[9] = a.m[9];
|
||||
m[10] = a.m[10];
|
||||
m[11] = a.m[11];
|
||||
|
||||
m[12] = a.m[12];
|
||||
m[13] = a.m[13];
|
||||
m[14] = a.m[14];
|
||||
m[15] = a.m[15];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* constructor from quaternion
|
||||
*/
|
||||
inline Matrix4x4Template( const QuaternionTemplate<T> &q )
|
||||
{
|
||||
m[0] = 1 - 2*q.y*q.y - 2*q.z*q.z;
|
||||
m[1] = 2*q.x*q.y - 2*q.z*q.w;
|
||||
m[2] = 2*q.x*q.z + 2*q.y*q.w;
|
||||
m[3] = static_cast<T>(0);
|
||||
|
||||
m[4] = 2*q.x*q.y + 2*q.z*q.w;
|
||||
m[5] = 1 - 2*q.x*q.x - 2*q.z*q.z;
|
||||
m[6] = 2*q.y*q.z - 2*q.x*q.w;
|
||||
m[7] = static_cast<T>(0);
|
||||
|
||||
m[8] = 2*q.x*q.z - 2*q.y*q.w;
|
||||
m[9] = 2*q.y*q.z + 2*q.x*q.w;
|
||||
m[10] = 1 - 2*q.x*q.x - 2*q.y*q.y;
|
||||
m[11] = static_cast<T>(0);
|
||||
|
||||
m[12] = static_cast<T>(0);
|
||||
m[13] = static_cast<T>(0);
|
||||
m[14] = static_cast<T>(0);
|
||||
m[15] = static_cast<T>(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* constructor from quaternion and translation vector
|
||||
*/
|
||||
inline Matrix4x4Template(
|
||||
const QuaternionTemplate<T> &q,
|
||||
const Vector3Template<T> &a )
|
||||
{
|
||||
m[0] = 1 - 2*q.y*q.y - 2*q.z*q.z;
|
||||
m[1] = 2*q.x*q.y - 2*q.z*q.w;
|
||||
m[2] = 2*q.x*q.z + 2*q.y*q.w;
|
||||
m[3] = static_cast<T>(0);
|
||||
|
||||
m[4] = 2*q.x*q.y + 2*q.z*q.w;
|
||||
m[5] = 1 - 2*q.x*q.x - 2*q.z*q.z;
|
||||
m[6] = 2*q.y*q.z - 2*q.x*q.w;
|
||||
m[7] = static_cast<T>(0);
|
||||
|
||||
m[8] = 2*q.x*q.z - 2*q.y*q.w;
|
||||
m[9] = 2*q.y*q.z + 2*q.x*q.w;
|
||||
m[10] = 1 - 2*q.x*q.x - 2*q.y*q.y;
|
||||
m[11] = static_cast<T>(0);
|
||||
|
||||
m[12] = a.x;
|
||||
m[13] = a.y;
|
||||
m[14] = a.z;
|
||||
m[15] = static_cast<T>(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* constructor from heading, up and translation vectors
|
||||
*/
|
||||
inline Matrix4x4Template(
|
||||
const Vector3Template<T> &h,
|
||||
const Vector3Template<T> &u,
|
||||
const Vector3Template<T> &t )
|
||||
{
|
||||
Vector3Template<T> a, b, c;
|
||||
c = h.unit();
|
||||
a = h.crossProduct( u ).unit();
|
||||
b = c.crossProduct( a ).unit();
|
||||
|
||||
m[0] = a.x;
|
||||
m[1] = b.x;
|
||||
m[2] = c.x;
|
||||
m[3] = static_cast<T>(0);
|
||||
|
||||
m[4] = a.y;
|
||||
m[5] = b.y;
|
||||
m[6] = c.y;
|
||||
m[7] = static_cast<T>(0);
|
||||
|
||||
m[8] = a.z;
|
||||
m[9] = b.z;
|
||||
m[10] = c.z;
|
||||
m[11] = static_cast<T>(0);
|
||||
|
||||
m[12] = t.x;
|
||||
m[13] = t.y;
|
||||
m[14] = t.z;
|
||||
m[15] = static_cast<T>(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* contructor from euler angles
|
||||
*/
|
||||
inline Matrix4x4Template(
|
||||
T a,
|
||||
T e,
|
||||
T t,
|
||||
const Vector3Template<T> &tr )
|
||||
{
|
||||
T ch = cos( a );
|
||||
T sh = sin( a );
|
||||
T ca = cos( e );
|
||||
T sa = sin( e );
|
||||
T cb = cos( t );
|
||||
T sb = sin( t );
|
||||
|
||||
m[0] = ch * ca;
|
||||
m[1] = sh*sb - ch*sa*cb;
|
||||
m[2] = ch*sa*sb + sh*cb;
|
||||
m[3] = static_cast<T>(0);
|
||||
|
||||
m[4] = sa;
|
||||
m[5] = ca*cb;
|
||||
m[6] = -ca*sb;
|
||||
m[7] = static_cast<T>(0);
|
||||
|
||||
|
||||
m[8] = -sh*ca;
|
||||
m[9] = sh*sa*cb + ch*sb;
|
||||
m[10] = -sh*sa*sb + ch*cb;
|
||||
m[11] = static_cast<T>(0);
|
||||
|
||||
m[12] = tr.x;
|
||||
m[13] = tr.y;
|
||||
m[14] = tr.z;
|
||||
m[15] = static_cast<T>(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* transpose this matrix
|
||||
*/
|
||||
inline void transpose()
|
||||
{
|
||||
std::swap( m[4], m[1] );
|
||||
std::swap( m[8], m[2] );
|
||||
std::swap( m[12], m[3] );
|
||||
|
||||
std::swap( m[9], m[6] );
|
||||
std::swap( m[13], m[7] );
|
||||
std::swap( m[14], m[11] );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get transposed matrix
|
||||
*/
|
||||
inline Matrix4x4Template<T> transposed()
|
||||
{
|
||||
Matrix4x4Template<T> a;
|
||||
|
||||
a.m[0] = m[0]; a.m[4] = m[1]; a.m[8] = m[2]; a.m[12] = m[3];
|
||||
a.m[1] = m[4]; a.m[5] = m[5]; a.m[9] = m[6]; a.m[13] = m[7];
|
||||
a.m[2] = m[8]; a.m[6] = m[9]; a.m[10] = m[10]; a.m[14] = m[11];
|
||||
a.m[3] = m[12]; a.m[7] = m[13]; a.m[11] = m[14]; a.m[15] = m[15];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* matrix multiplication
|
||||
*/
|
||||
template <class S>
|
||||
inline Matrix4x4Template<T> operator * ( const Matrix4x4Template<S> &a )
|
||||
{
|
||||
Matrix4x4Template<T> result;
|
||||
|
||||
result.m[0] = m[0] * static_cast<T>(a.m[0])
|
||||
+ m[4] * static_cast<T>(a.m[1])
|
||||
+ m[8] * static_cast<T>(a.m[2])
|
||||
+ m[12] * static_cast<T>(a.m[3]);
|
||||
|
||||
result.m[1] = m[1] * static_cast<T>(a.m[0])
|
||||
+ m[5] * static_cast<T>(a.m[1])
|
||||
+ m[9] * static_cast<T>(a.m[2])
|
||||
+ m[13] * static_cast<T>(a.m[3]);
|
||||
|
||||
result.m[2] = m[2] * static_cast<T>(a.m[0])
|
||||
+ m[6] * static_cast<T>(a.m[1])
|
||||
+ m[10] * static_cast<T>(a.m[2])
|
||||
+ m[14] * static_cast<T>(a.m[3]);
|
||||
|
||||
result.m[3] = m[3] * static_cast<T>(a.m[0])
|
||||
+ m[7] * static_cast<T>(a.m[1])
|
||||
+ m[11] * static_cast<T>(a.m[2])
|
||||
+ m[15] * static_cast<T>(a.m[3]);
|
||||
|
||||
|
||||
result.m[4] = m[0] * static_cast<T>(a.m[4])
|
||||
+ m[4] * static_cast<T>(a.m[5])
|
||||
+ m[8] * static_cast<T>(a.m[6])
|
||||
+ m[12] * static_cast<T>(a.m[7]);
|
||||
|
||||
result.m[5] = m[1] * static_cast<T>(a.m[4])
|
||||
+ m[5] * static_cast<T>(a.m[5])
|
||||
+ m[9] * static_cast<T>(a.m[6])
|
||||
+ m[13] * static_cast<T>(a.m[7]);
|
||||
|
||||
result.m[6] = m[2] * static_cast<T>(a.m[4])
|
||||
+ m[6] * static_cast<T>(a.m[5])
|
||||
+ m[10] * static_cast<T>(a.m[6])
|
||||
+ m[14] * static_cast<T>(a.m[7]);
|
||||
|
||||
result.m[7] = m[3] * static_cast<T>(a.m[4])
|
||||
+ m[7] * static_cast<T>(a.m[5])
|
||||
+ m[11] * static_cast<T>(a.m[6])
|
||||
+ m[15] * static_cast<T>(a.m[7]);
|
||||
|
||||
|
||||
result.m[8] = m[0] * static_cast<T>(a.m[8])
|
||||
+ m[4] * static_cast<T>(a.m[9])
|
||||
+ m[8] * static_cast<T>(a.m[10])
|
||||
+ m[12] * static_cast<T>(a.m[11]);
|
||||
|
||||
result.m[9] = m[1] * static_cast<T>(a.m[8])
|
||||
+ m[5] * static_cast<T>(a.m[9])
|
||||
+ m[9] * static_cast<T>(a.m[10])
|
||||
+ m[13] * static_cast<T>(a.m[11]);
|
||||
|
||||
result.m[10] = m[2] * static_cast<T>(a.m[8])
|
||||
+ m[6] * static_cast<T>(a.m[9])
|
||||
+ m[10] * static_cast<T>(a.m[10])
|
||||
+ m[14] * static_cast<T>(a.m[11]);
|
||||
|
||||
result.m[11] = m[3] * static_cast<T>(a.m[8])
|
||||
+ m[7] * static_cast<T>(a.m[9])
|
||||
+ m[11] * static_cast<T>(a.m[10])
|
||||
+ m[15] * static_cast<T>(a.m[11]);
|
||||
|
||||
|
||||
result.m[12] = m[0] * static_cast<T>(a.m[12])
|
||||
+ m[4] * static_cast<T>(a.m[13])
|
||||
+ m[8] * static_cast<T>(a.m[14])
|
||||
+ m[12] * static_cast<T>(a.m[15]);
|
||||
|
||||
result.m[13] = m[1] * static_cast<T>(a.m[12])
|
||||
+ m[5] * static_cast<T>(a.m[13])
|
||||
+ m[9] * static_cast<T>(a.m[14])
|
||||
+ m[13] * static_cast<T>(a.m[15]);
|
||||
|
||||
result.m[14] = m[2] * static_cast<T>(a.m[12])
|
||||
+ m[6] * static_cast<T>(a.m[13])
|
||||
+ m[10] * static_cast<T>(a.m[14])
|
||||
+ m[14] * static_cast<T>(a.m[15]);
|
||||
|
||||
result.m[15] = m[3] * static_cast<T>(a.m[12])
|
||||
+ m[7] * static_cast<T>(a.m[13])
|
||||
+ m[11] * static_cast<T>(a.m[14])
|
||||
+ m[15] * static_cast<T>(a.m[15]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* matrix multiplication
|
||||
*/
|
||||
/*
|
||||
template <class S>
|
||||
inline Matrix4x4Template<T> operator *= ( const Matrix4x4Template<S> &a )
|
||||
{
|
||||
Matrix4x4Template<T> result;
|
||||
|
||||
result.m[0] = m[0] * static_cast<T>(a.m[0])
|
||||
+ m[4] * static_cast<T>(a.m[1])
|
||||
+ m[8] * static_cast<T>(a.m[2]);
|
||||
+ m[12] * static_cast<T>(a.m[3]);
|
||||
|
||||
result.m[1] = m[1] * static_cast<T>(a.m[0])
|
||||
+ m[5] * static_cast<T>(a.m[1])
|
||||
+ m[9] * static_cast<T>(a.m[2]);
|
||||
+ m[13] * static_cast<T>(a.m[3]);
|
||||
|
||||
result.m[2] = m[2] * static_cast<T>(a.m[0])
|
||||
+ m[6] * static_cast<T>(a.m[1])
|
||||
+ m[10] * static_cast<T>(a.m[2]);
|
||||
+ m[14] * static_cast<T>(a.m[3]);
|
||||
|
||||
result.m[3] = m[3] * static_cast<T>(a.m[0])
|
||||
+ m[7] * static_cast<T>(a.m[1])
|
||||
+ m[11] * static_cast<T>(a.m[2]);
|
||||
+ m[15] * static_cast<T>(a.m[3]);
|
||||
|
||||
|
||||
result.m[4] = m[0] * static_cast<T>(a.m[4])
|
||||
+ m[4] * static_cast<T>(a.m[5])
|
||||
+ m[8] * static_cast<T>(a.m[6]);
|
||||
+ m[12] * static_cast<T>(a.m[7]);
|
||||
|
||||
result.m[5] = m[1] * static_cast<T>(a.m[4])
|
||||
+ m[5] * static_cast<T>(a.m[5])
|
||||
+ m[9] * static_cast<T>(a.m[6]);
|
||||
+ m[13] * static_cast<T>(a.m[7]);
|
||||
|
||||
result.m[6] = m[2] * static_cast<T>(a.m[4])
|
||||
+ m[6] * static_cast<T>(a.m[5])
|
||||
+ m[10] * static_cast<T>(a.m[6]);
|
||||
+ m[14] * static_cast<T>(a.m[7]);
|
||||
|
||||
result.m[7] = m[3] * static_cast<T>(a.m[4])
|
||||
+ m[7] * static_cast<T>(a.m[5])
|
||||
+ m[11] * static_cast<T>(a.m[6]);
|
||||
+ m[15] * static_cast<T>(a.m[7]);
|
||||
|
||||
|
||||
result.m[8] = m[0] * static_cast<T>(a.m[8])
|
||||
+ m[4] * static_cast<T>(a.m[9])
|
||||
+ m[8] * static_cast<T>(a.m[10]);
|
||||
+ m[12] * static_cast<T>(a.m[11]);
|
||||
|
||||
result.m[9] = m[1] * static_cast<T>(a.m[8])
|
||||
+ m[5] * static_cast<T>(a.m[9])
|
||||
+ m[9] * static_cast<T>(a.m[10]);
|
||||
+ m[13] * static_cast<T>(a.m[11]);
|
||||
|
||||
result.m[10] = m[2] * static_cast<T>(a.m[8])
|
||||
+ m[6] * static_cast<T>(a.m[9])
|
||||
+ m[10] * static_cast<T>(a.m[10]);
|
||||
+ m[14] * static_cast<T>(a.m[11]);
|
||||
|
||||
result.m[11] = m[3] * static_cast<T>(a.m[8])
|
||||
+ m[7] * static_cast<T>(a.m[9])
|
||||
+ m[11] * static_cast<T>(a.m[10]);
|
||||
+ m[15] * static_cast<T>(a.m[11]);
|
||||
|
||||
|
||||
result.m[12] = m[0] * static_cast<T>(a.m[12])
|
||||
+ m[4] * static_cast<T>(a.m[13])
|
||||
+ m[8] * static_cast<T>(a.m[14]);
|
||||
+ m[12] * static_cast<T>(a.m[15]);
|
||||
|
||||
result.m[13] = m[1] * static_cast<T>(a.m[12])
|
||||
+ m[5] * static_cast<T>(a.m[13])
|
||||
+ m[9] * static_cast<T>(a.m[14]);
|
||||
+ m[13] * static_cast<T>(a.m[15]);
|
||||
|
||||
result.m[14] = m[2] * static_cast<T>(a.m[12])
|
||||
+ m[6] * static_cast<T>(a.m[13])
|
||||
+ m[10] * static_cast<T>(a.m[14]);
|
||||
+ m[14] * static_cast<T>(a.m[15]);
|
||||
|
||||
result.m[15] = m[3] * static_cast<T>(a.m[12])
|
||||
+ m[7] * static_cast<T>(a.m[13])
|
||||
+ m[11] * static_cast<T>(a.m[14]);
|
||||
+ m[15] * static_cast<T>(a.m[15]);
|
||||
|
||||
m = result.m;
|
||||
|
||||
return *this;
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* matrix vector multiplication
|
||||
*/
|
||||
Vector3Template<T> operator * ( const Vector3Template<T> &a )
|
||||
{
|
||||
Vector3Template<T> result;
|
||||
|
||||
result.x = m[0] * a.x + m[4] * a.y + m[8] * a.z + m[12];
|
||||
result.y = m[1] * a.x + m[5] * a.y + m[9] * a.z + m[13];
|
||||
result.z = m[2] * a.x + m[6] * a.y + m[11] * a.z + m[14];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
T *data()
|
||||
{
|
||||
return &m[0];
|
||||
}
|
||||
};
|
||||
|
||||
typedef Matrix4x4Template<float> Matrix4x4Float;
|
||||
typedef Matrix4x4Template<double> Matrix4x4Double;
|
||||
typedef Matrix4x4Template<Scalar> Matrix4x4;
|
||||
|
||||
} // namespace bc
|
||||
|
||||
#endif // BLUECORE_MATRIX_H
|
51
engine/Math/Plane.h
Normal file
51
engine/Math/Plane.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef BLUECORE_PLANE_H
|
||||
#define BLUECORE_PLANE_H
|
||||
|
||||
#include "Scalar.h"
|
||||
#include "Vector.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
template <class T>
|
||||
class PlaneTemplate
|
||||
{
|
||||
public:
|
||||
Vector3Template<T> _n;
|
||||
T _d;
|
||||
|
||||
/**
|
||||
* contructor
|
||||
*/
|
||||
inline PlaneTemplate() : _d( 0. )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* contructor
|
||||
*/
|
||||
inline PlaneTemplate(
|
||||
Vector3Template<T> a,
|
||||
Vector3Template<T> b,
|
||||
Vector3Template<T> c )
|
||||
{
|
||||
_n = (a - b).cross(a - c).normalized();
|
||||
_d = _n.dot( a );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* distance
|
||||
*/
|
||||
inline T distance( const Vector3Template<T> a )
|
||||
{
|
||||
return _n.dot( a ) - _d;
|
||||
}
|
||||
};
|
||||
|
||||
typedef PlaneTemplate<float> PlaneFloat;
|
||||
typedef PlaneTemplate<double> PlaneDouble;
|
||||
typedef PlaneTemplate<Scalar> Plane;
|
||||
}
|
||||
|
||||
#endif
|
57
engine/Math/Point.h
Normal file
57
engine/Math/Point.h
Normal file
@ -0,0 +1,57 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Author: Gero Mueller <gero.mueller@cloo.de>
|
||||
// Copyright: (c) 2006 Gero Mueller
|
||||
// License: MIT License
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BLUECORE_POINT_H
|
||||
#define BLUECORE_POINT_H
|
||||
|
||||
#include "rectangle.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
template<typename type>
|
||||
struct Rectangle2DTemplate;
|
||||
|
||||
template<typename type>
|
||||
struct Point2DTemplate
|
||||
{
|
||||
type _x, _y;
|
||||
|
||||
Point2DTemplate() : _x(0), _y(0)
|
||||
{
|
||||
}
|
||||
|
||||
Point2DTemplate( type x, type y ) : _x(x), _y(y)
|
||||
{
|
||||
}
|
||||
|
||||
bool in( const Rectangle2DTemplate<type> &rect );
|
||||
};
|
||||
|
||||
#include "rectangle.h"
|
||||
|
||||
template<typename type>
|
||||
bool Point2DTemplate<type>::in( const Rectangle2DTemplate<type> &rect )
|
||||
{
|
||||
if( _x < rect._x )
|
||||
return false;
|
||||
|
||||
if( _x > (rect._x + rect._width) )
|
||||
return false;
|
||||
|
||||
if( _y < rect._y )
|
||||
return false;
|
||||
|
||||
if( _y > (rect._y + rect._height) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef Point2DTemplate<int> Point2D;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
366
engine/Math/Quaternion.h
Normal file
366
engine/Math/Quaternion.h
Normal file
@ -0,0 +1,366 @@
|
||||
#ifndef BLUECORE_QUATERNION_H
|
||||
#define BLUECORE_QUATERNION_H
|
||||
|
||||
#include "Vector.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
template <class T>
|
||||
class QuaternionTemplate
|
||||
{
|
||||
public:
|
||||
T w, x, y, z;
|
||||
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
inline QuaternionTemplate()
|
||||
{
|
||||
w = static_cast<T>(1.0);
|
||||
x = static_cast<T>(0.0);
|
||||
y = static_cast<T>(0.0);
|
||||
z = static_cast<T>(0.0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* contructor
|
||||
*/
|
||||
template <class S>
|
||||
inline QuaternionTemplate( S w, S x, S y, S z )
|
||||
{
|
||||
this->w = static_cast<T>(w);
|
||||
this->x = static_cast<T>(x);
|
||||
this->y = static_cast<T>(y);
|
||||
this->z = static_cast<T>(z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* contructor
|
||||
*/
|
||||
template <class S>
|
||||
inline QuaternionTemplate( Vector3Template<S> axis, S angle )
|
||||
{
|
||||
T half_angle = static_cast<T>(angle)/static_cast<T>(2.0);
|
||||
T sin_half_angle = static_cast<T>( sin( half_angle ) );
|
||||
|
||||
w = static_cast<T>( cos( half_angle ) );
|
||||
x = sin_half_angle * static_cast<T>(axis.x);
|
||||
y = sin_half_angle * static_cast<T>(axis.y);
|
||||
z = sin_half_angle * static_cast<T>(axis.z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* contructor
|
||||
*/
|
||||
template <class S>
|
||||
inline QuaternionTemplate( S h, S a, S b )
|
||||
{
|
||||
T c1 = static_cast<T>( cos(h / 2.0) );
|
||||
T c2 = static_cast<T>( cos(a / 2.0) );
|
||||
T c3 = static_cast<T>( cos(b / 2.0) );
|
||||
T s1 = static_cast<T>( sin(h / 2.0) );
|
||||
T s2 = static_cast<T>( sin(a / 2.0) );
|
||||
T s3 = static_cast<T>( sin(b / 2.0) );
|
||||
|
||||
w = c1 * c2 * c3 - s1 * s2 * s3;
|
||||
x = s1 * s2 * c3 + c1 * c2 * s3;
|
||||
y = s1 * c2 * c3 + c1 * s2 * s3;
|
||||
z = c1 * s2 * c3 - s1 * c2 * s3;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* identity
|
||||
*/
|
||||
inline void identity()
|
||||
{
|
||||
w = static_cast<T>(1.0);
|
||||
x = static_cast<T>(0.0);
|
||||
y = static_cast<T>(0.0);
|
||||
z = static_cast<T>(0.0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* operator +
|
||||
*/
|
||||
template <class S>
|
||||
inline QuaternionTemplate<T> operator + (
|
||||
const QuaternionTemplate<S> &a ) const
|
||||
{
|
||||
return QuaternionTemplate<T>(
|
||||
w + static_cast<T>(a.w),
|
||||
x + static_cast<T>(a.x),
|
||||
y + static_cast<T>(a.y),
|
||||
z + static_cast<T>(a.z) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* operator +=
|
||||
*/
|
||||
template <class S>
|
||||
inline QuaternionTemplate<T> &operator += (
|
||||
const QuaternionTemplate<S> &a )
|
||||
{
|
||||
w += static_cast<T>(a.w);
|
||||
x += static_cast<T>(a.x);
|
||||
y += static_cast<T>(a.y);
|
||||
z += static_cast<T>(a.z);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* operator -
|
||||
*/
|
||||
template <class S>
|
||||
inline QuaternionTemplate<T> operator - (
|
||||
const QuaternionTemplate<S> &a ) const
|
||||
{
|
||||
return QuaternionTemplate<T>(
|
||||
w - static_cast<T>(a.w),
|
||||
x - static_cast<T>(a.x),
|
||||
y - static_cast<T>(a.y),
|
||||
z - static_cast<T>(a.z) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* operator *
|
||||
*/
|
||||
template <class S>
|
||||
inline QuaternionTemplate<T> operator * (
|
||||
const QuaternionTemplate<S> &a ) const
|
||||
{
|
||||
return QuaternionTemplate<T>(
|
||||
w * static_cast<T>(a.w) -
|
||||
x * static_cast<T>(a.x) -
|
||||
y * static_cast<T>(a.y) -
|
||||
z * static_cast<T>(a.z),
|
||||
w * static_cast<T>(a.x) +
|
||||
x * static_cast<T>(a.w) +
|
||||
y * static_cast<T>(a.z) -
|
||||
z * static_cast<T>(a.y),
|
||||
w * static_cast<T>(a.y) -
|
||||
x * static_cast<T>(a.z) +
|
||||
y * static_cast<T>(a.w) +
|
||||
z * static_cast<T>(a.x),
|
||||
w * static_cast<T>(a.z) +
|
||||
x * static_cast<T>(a.y) -
|
||||
y * static_cast<T>(a.x) +
|
||||
z * static_cast<T>(a.w) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* operator *=
|
||||
*/
|
||||
template <class S>
|
||||
inline QuaternionTemplate<T> &operator *=(
|
||||
const QuaternionTemplate<S> &a )
|
||||
{
|
||||
w = w * static_cast<T>(a.w) - x * static_cast<T>(a.x) -
|
||||
y * static_cast<T>(a.y) - z * static_cast<T>(a.z);
|
||||
x = w * static_cast<T>(a.x) + x * static_cast<T>(a.w) +
|
||||
y * static_cast<T>(a.z) - z * static_cast<T>(a.y);
|
||||
y = w * static_cast<T>(a.y) - x * static_cast<T>(a.z) +
|
||||
y * static_cast<T>(a.w) + z * static_cast<T>(a.x);
|
||||
z = w * static_cast<T>(a.z) + x * static_cast<T>(a.y) -
|
||||
y * static_cast<T>(a.x) + z * static_cast<T>(a.w);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* operator -=
|
||||
*/
|
||||
template <class S>
|
||||
inline QuaternionTemplate<T> &operator -= (
|
||||
const QuaternionTemplate<S> &a )
|
||||
{
|
||||
w -= static_cast<T>(a.w);
|
||||
x -= static_cast<T>(a.x);
|
||||
y -= static_cast<T>(a.y);
|
||||
z -= static_cast<T>(a.z);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* operator =
|
||||
*/
|
||||
template <class S>
|
||||
inline QuaternionTemplate<T> &operator = (
|
||||
const QuaternionTemplate<S> &a )
|
||||
{
|
||||
w = static_cast<T>(a.w);
|
||||
x = static_cast<T>(a.x);
|
||||
y = static_cast<T>(a.y);
|
||||
z = static_cast<T>(a.z);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* unit
|
||||
*/
|
||||
inline QuaternionTemplate<T> unit() const
|
||||
{
|
||||
T d = 1/sqrt( w*w + x*x + y*y + z*z );
|
||||
return QuaternionTemplate<T>( w * d, x * d, y * d, z * d );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* inversed
|
||||
*/
|
||||
inline QuaternionTemplate<T> inversed() const
|
||||
{
|
||||
return QuaternionTemplate<T>( w, -x, -y, -z );
|
||||
}
|
||||
|
||||
/**
|
||||
* inversed
|
||||
*/
|
||||
inline void inverse()
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* normalize
|
||||
*/
|
||||
inline QuaternionTemplate<T> &normalize()
|
||||
{
|
||||
T d = 1/sqrt( w*w + x*x + y*y + z*z );
|
||||
w *= d;
|
||||
x *= d;
|
||||
y *= d;
|
||||
z *= d;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* apply
|
||||
*/
|
||||
template <class S>
|
||||
inline const Vector3Template<T> apply(
|
||||
const Vector3Template<S> &a ) const
|
||||
{
|
||||
T xx = x*x, xy = x*y, xz = x*z, xw = x*w,
|
||||
yy = y*y, yz = y*z, yw = y*w,
|
||||
zz = z*z, zw = z*w;
|
||||
|
||||
return Vector3Template<T>(
|
||||
2.0 * ( static_cast<T>(a.x) * ( 0.5 - yy - zz ) +
|
||||
static_cast<T>(a.y) * ( xy - zw ) +
|
||||
static_cast<T>(a.z) * ( xz + yw ) ),
|
||||
|
||||
2.0 * ( static_cast<T>(a.x) * ( xy + zw ) +
|
||||
static_cast<T>(a.y) * ( 0.5 - xx - zz ) +
|
||||
static_cast<T>(a.z) * ( yz - xw ) ),
|
||||
|
||||
2.0 * ( static_cast<T>(a.x) * ( xz - yw ) +
|
||||
static_cast<T>(a.y) * ( yz + xw ) +
|
||||
static_cast<T>(a.z) * ( 0.5 - xx - yy ) ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* apply
|
||||
*/
|
||||
template <class S>
|
||||
inline const Vector3Template<T> operator * (
|
||||
const Vector3Template<S> &a ) const
|
||||
{
|
||||
T xx = x*x, xy = x*y, xz = x*z, xw = x*w,
|
||||
yy = y*y, yz = y*z, yw = y*w,
|
||||
zz = z*z, zw = z*w;
|
||||
|
||||
return Vector3Template<T>(
|
||||
2.0 * ( static_cast<T>(a.x) * ( 0.5 - yy - zz ) +
|
||||
static_cast<T>(a.y) * ( xy - zw ) +
|
||||
static_cast<T>(a.z) * ( xz + yw ) ),
|
||||
|
||||
2.0 * ( static_cast<T>(a.x) * ( xy + zw ) +
|
||||
static_cast<T>(a.y) * ( 0.5 - xx - zz ) +
|
||||
static_cast<T>(a.z) * ( yz - xw ) ),
|
||||
|
||||
2.0 * ( static_cast<T>(a.x) * ( xz - yw ) +
|
||||
static_cast<T>(a.y) * ( yz + xw ) +
|
||||
static_cast<T>(a.z) * ( 0.5 - xx - yy ) ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* applyInversed
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template<T> applyInversed(
|
||||
const Vector3Template<S> &a ) const
|
||||
{
|
||||
T xx = x*x, xy = x*y, xz = x*z, xw = -x*w,
|
||||
yy = y*y, yz = y*z, yw = -y*w,
|
||||
zz = z*z, zw = -z*w;
|
||||
|
||||
return Vector3Template<T>(
|
||||
2.0 * ( static_cast<T>(a.x) * ( 0.5 - yy - zz ) +
|
||||
static_cast<T>(a.y) * ( xy - zw ) +
|
||||
static_cast<T>(a.z) * ( xz + yw ) ),
|
||||
|
||||
2.0 * ( static_cast<T>(a.x) * ( xy + zw ) +
|
||||
static_cast<T>(a.y) * ( 0.5 - xx - zz ) +
|
||||
static_cast<T>(a.z) * ( yz - xw ) ),
|
||||
|
||||
2.0 * ( static_cast<T>(a.x) * ( xz - yw ) +
|
||||
static_cast<T>(a.y) * ( yz + xw ) +
|
||||
static_cast<T>(a.z) * ( 0.5 - xx - yy ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* transform from ode to gl coodinates
|
||||
*/
|
||||
inline QuaternionTemplate<T> toGl() const
|
||||
{
|
||||
return QuaternionTemplate<T>( w, x, z, -y );
|
||||
}
|
||||
|
||||
/**
|
||||
* transform from gl to ode coodinates
|
||||
*/
|
||||
inline QuaternionTemplate<T> toOde() const
|
||||
{
|
||||
return QuaternionTemplate<T>( w, x, -z, y );
|
||||
}
|
||||
|
||||
inline QuaternionTemplate<T> slerp( const QuaternionTemplate<T> &q, const Scalar &t )
|
||||
{
|
||||
Scalar phi = acos(w*q.w + x*q.x + y*q.y + z*q.z);
|
||||
Scalar s = 1 / sin(phi);
|
||||
Scalar a = sin(phi*(1-t)) * s;
|
||||
Scalar b = sin(phi*t) * s;
|
||||
|
||||
return QuaternionTemplate<T>( a*w+b*q.w, a*x+b*q.x, a*y+b*q.y, a*z+b*q.z );
|
||||
}
|
||||
};
|
||||
|
||||
typedef QuaternionTemplate<float> QuaternionFloat;
|
||||
typedef QuaternionTemplate<double> QuaternionDouble;
|
||||
typedef QuaternionTemplate<Scalar> Quaternion;
|
||||
}
|
||||
|
||||
#endif
|
119
engine/Math/Ray.h
Normal file
119
engine/Math/Ray.h
Normal file
@ -0,0 +1,119 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Author: Gero Mueller <gero.mueller@cloo.de>
|
||||
// Copyright: (c) 2006 Gero Mueller
|
||||
// License: MIT License
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BLUECORE_RAY_H
|
||||
#define BLUECORE_RAY_H
|
||||
|
||||
#include "scalar.h"
|
||||
#include "vector.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
template <class T>
|
||||
class RayTemplate
|
||||
{
|
||||
Vector3Template<T> point, direction;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* normalize the vector to length 1
|
||||
*/
|
||||
inline RayTemplate()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* constructor from point and direction
|
||||
*/
|
||||
template <class S>
|
||||
inline RayTemplate(
|
||||
const Vector3Template<S> &point,
|
||||
const Vector3Template<S> &direction )
|
||||
{
|
||||
this->point = point;
|
||||
this->direction = direction.normalized();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set the point
|
||||
*/
|
||||
template <class S>
|
||||
inline setPoint( const Vector3Template<S> &point )
|
||||
{
|
||||
this->point = point;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set the direction
|
||||
*/
|
||||
template <class S>
|
||||
inline setDirection( const Vector3Template<S> &direction )
|
||||
{
|
||||
this->direction = direction.normalized();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get point
|
||||
*/
|
||||
inline const Vector3Template<T> &getPoint() const
|
||||
{
|
||||
return point;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get direction
|
||||
*/
|
||||
inline const Vector3Template<T> &getDirection() const
|
||||
{
|
||||
return direction;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* checks if a point lies on the ray
|
||||
*/
|
||||
template <class S>
|
||||
inline bool contains( const Vector3Template<T> &a )
|
||||
{
|
||||
return (a - point).parallel( direction );
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate the distance between a point and the ray
|
||||
*/
|
||||
template <class S>
|
||||
inline T distance( const Vector3Template<S> &a ) const
|
||||
{
|
||||
T t = direction.dot( a - point );
|
||||
Vector3Template<T> b = at(t) - a;
|
||||
return b.length();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gets the position at distance t
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template<S> at( const T a ) const
|
||||
{
|
||||
return Vector3Template<T>( point + direction * a );
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
typedef RayTemplate<float> RayFloat;
|
||||
typedef RayTemplate<double> RayDouble;
|
||||
typedef RayTemplate<Scalar> Ray;
|
||||
}
|
||||
|
||||
#endif
|
91
engine/Math/Rectangle.h
Normal file
91
engine/Math/Rectangle.h
Normal file
@ -0,0 +1,91 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Author: Gero Mueller <gero.mueller@cloo.de>
|
||||
// Copyright: (c) 2006 Gero Mueller
|
||||
// License: MIT License
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BLUECORE_RECTANGLE_H
|
||||
#define BLUECORE_RECTANGLE_H
|
||||
|
||||
#include "point.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
template<typename type>
|
||||
struct Rectangle2DTemplate
|
||||
{
|
||||
type _x, _y, _width, _height;
|
||||
|
||||
Rectangle2DTemplate() :
|
||||
_x(0),
|
||||
_y(0),
|
||||
_width(0),
|
||||
_height(0)
|
||||
{
|
||||
}
|
||||
|
||||
Rectangle2DTemplate( int x, int y, int width, int height ) :
|
||||
_x(x),
|
||||
_y(y),
|
||||
_width(width),
|
||||
_height(height)
|
||||
{
|
||||
}
|
||||
|
||||
Rectangle2DTemplate( const Point2DTemplate<type> &topLeft, const Point2DTemplate<type> &bottomRight ) :
|
||||
_x(topLeft._x),
|
||||
_y(topLeft._y),
|
||||
_width(bottomRight._x - topLeft._x),
|
||||
_height(bottomRight._y - topLeft._y)
|
||||
{
|
||||
}
|
||||
|
||||
Rectangle2DTemplate &operator=(const Rectangle2DTemplate<type> &rect)
|
||||
{
|
||||
_x = rect._x;
|
||||
_y = rect._y;
|
||||
_width = rect._width;
|
||||
_height = rect._height;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool overlaps( const Rectangle2DTemplate<type> &rect )
|
||||
{
|
||||
if( (rect._x + rect._width) < _x )
|
||||
return false;
|
||||
|
||||
if( rect._x > (_x + _width) )
|
||||
return false;
|
||||
|
||||
if( rect._y < (_y - _height) )
|
||||
return false;
|
||||
|
||||
if( (rect._y - rect._height) > _y )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool contains( const Point2DTemplate<type> &point ) const
|
||||
{
|
||||
if( point._x < _x )
|
||||
return false;
|
||||
|
||||
if( point._y < _y )
|
||||
return false;
|
||||
|
||||
if( point._x > (_x + _width) )
|
||||
return false;
|
||||
|
||||
if( point._y > (_y + _height) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Rectangle2DTemplate<int> Rectangle2D;
|
||||
}
|
||||
|
||||
#endif
|
19
engine/Math/Scalar.h
Normal file
19
engine/Math/Scalar.h
Normal file
@ -0,0 +1,19 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Author: Gero Mueller <gero.mueller@cloo.de>
|
||||
// Copyright: (c) 2006 Gero Mueller
|
||||
// License: MIT License
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BLUECORE_COMMON_H
|
||||
#define BLUECORE_COMMON_H
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
/* Scalar defines the default floating point type */
|
||||
typedef double Scalar;
|
||||
|
||||
const Scalar Pi = 3.141592653589793;
|
||||
|
||||
} // namespace bc
|
||||
|
||||
#endif // BLUECORE_COMMON_H
|
51
engine/Math/Transformation.h
Normal file
51
engine/Math/Transformation.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef BLUECORE_TRANSFORMATION_H
|
||||
#define BLUECORE_TRANSFORMATION_H
|
||||
|
||||
#include "Quaternion.h"
|
||||
#include "Vector.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
template<class T> class TransformationTemplate
|
||||
{
|
||||
public:
|
||||
|
||||
QuaternionTemplate<T> rotation;
|
||||
Vector3Template<T> translation;
|
||||
|
||||
TransformationTemplate()
|
||||
{
|
||||
}
|
||||
|
||||
template<class S> TransformationTemplate(
|
||||
const QuaternionTemplate<S> &rot) :
|
||||
rotation(rot)
|
||||
{
|
||||
}
|
||||
|
||||
template<class S> TransformationTemplate(
|
||||
const Vector3Template<S> &trans) :
|
||||
translation(trans)
|
||||
{
|
||||
}
|
||||
|
||||
template<class R, class S> TransformationTemplate(
|
||||
const QuaternionTemplate<S> &rot,
|
||||
const Vector3Template<S> &trans) :
|
||||
rotation(rot), translation(trans)
|
||||
{
|
||||
}
|
||||
|
||||
template<class S> Vector3Template<T> transform(const Vector3Template<S> &v)
|
||||
{
|
||||
return rotation.apply(v) + translation;
|
||||
}
|
||||
};
|
||||
|
||||
typedef TransformationTemplate<float> TransformationFloat;
|
||||
typedef TransformationTemplate<double> TransformationDouble;
|
||||
typedef TransformationTemplate<Scalar> Transformation;
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif /*TRANSFORMATION_H_*/
|
432
engine/Math/Vector.h
Normal file
432
engine/Math/Vector.h
Normal file
@ -0,0 +1,432 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Author: Gero Mueller <gero.mueller@cloo.de>
|
||||
// Copyright: (c) 2006 Gero Mueller
|
||||
// License: MIT License
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BLUECORE_VECTOR_H
|
||||
#define BLUECORE_VECTOR_H
|
||||
|
||||
// system includes
|
||||
#include <cmath>
|
||||
#include <ostream>
|
||||
|
||||
// project includes
|
||||
#include "Scalar.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
template <class T>
|
||||
class Vector3Template
|
||||
{
|
||||
public:
|
||||
|
||||
T x, y, z;
|
||||
|
||||
/**
|
||||
* Default Contructor
|
||||
*/
|
||||
inline Vector3Template()
|
||||
{
|
||||
x = static_cast<T>(0);
|
||||
y = static_cast<T>(0);
|
||||
z = static_cast<T>(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor from three values
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template( S x, S y, S z )
|
||||
{
|
||||
this->x = static_cast<T>(x);
|
||||
this->y = static_cast<T>(y);
|
||||
this->z = static_cast<T>(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* copy contructor
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template( Vector3Template<S> &a )
|
||||
{
|
||||
x = static_cast<T>(a.x);
|
||||
y = static_cast<T>(a.y);
|
||||
z = static_cast<T>(a.z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* add operataor
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template<T> operator + (
|
||||
const Vector3Template<S> &a ) const
|
||||
{
|
||||
return Vector3Template<T>(
|
||||
x + static_cast<T>(a.x),
|
||||
y + static_cast<T>(a.y),
|
||||
z + static_cast<T>(a.z) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* zero the vector
|
||||
*/
|
||||
inline void zero()
|
||||
{
|
||||
x = static_cast<T>(0);
|
||||
y = static_cast<T>(0);
|
||||
z = static_cast<T>(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* zero the vector
|
||||
*/
|
||||
inline bool isZero() const
|
||||
{
|
||||
if( x != 0.0 )
|
||||
return false;
|
||||
|
||||
if( y != 0.0 )
|
||||
return false;
|
||||
|
||||
if( z != 0.0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* add-assign operator
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template<T> &operator += (
|
||||
const Vector3Template<S> &a )
|
||||
{
|
||||
x += static_cast<T>(a.x);
|
||||
y += static_cast<T>(a.y);
|
||||
z += static_cast<T>(a.z);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sub operator
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template<T> operator - (
|
||||
const Vector3Template<S> &a ) const
|
||||
{
|
||||
return Vector3Template<T>(
|
||||
x - static_cast<T>(a.x),
|
||||
y - static_cast<T>(a.y),
|
||||
z - static_cast<T>(a.z)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sub-assign operator
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template<T> &operator -= (
|
||||
const Vector3Template<S> &a )
|
||||
{
|
||||
x -= static_cast<T>(a.x);
|
||||
y -= static_cast<T>(a.y);
|
||||
z -= static_cast<T>(a.z);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* multiply by scalar operator
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template<T> operator * ( const S a ) const
|
||||
{
|
||||
return Vector3Template<T>(
|
||||
x * static_cast<T>(a),
|
||||
y * static_cast<T>(a),
|
||||
z * static_cast<T>(a)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* multiply-assign by scalar operator
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template<T> &operator *= ( const S a )
|
||||
{
|
||||
x *= static_cast<T>(a);
|
||||
y *= static_cast<T>(a);
|
||||
z *= static_cast<T>(a);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* divide by scalar operator
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template<T> operator / ( const S a ) const
|
||||
{
|
||||
return Vector3Template<T>(
|
||||
x / static_cast<T>(a),
|
||||
y / static_cast<T>(a),
|
||||
z / static_cast<T>(a)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* divide-assign by scalar operator
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template<T> &operator /= ( const S a )
|
||||
{
|
||||
x /= static_cast<T>(a);
|
||||
y /= static_cast<T>(a);
|
||||
z /= static_cast<T>(a);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* assign operator
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template<T> operator = (
|
||||
const Vector3Template<S> &a )
|
||||
{
|
||||
x = static_cast<T>(a.x);
|
||||
y = static_cast<T>(a.y);
|
||||
z = static_cast<T>(a.z);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector3Template<T> operator - (void) const
|
||||
{
|
||||
return Vector3Template<T>( -x, -y, -z );
|
||||
}
|
||||
|
||||
/**
|
||||
* compare operator
|
||||
*/
|
||||
template <class S>
|
||||
inline bool operator == ( const Vector3Template<S> &a )
|
||||
{
|
||||
if( x != static_cast<T>(a.x) )
|
||||
return false;
|
||||
|
||||
if( y != static_cast<T>(a.y) )
|
||||
return false;
|
||||
|
||||
if( z != static_cast<T>(a.z) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* anti compare operator
|
||||
*/
|
||||
template <class S>
|
||||
inline bool operator != ( const Vector3Template<S> &a )
|
||||
{
|
||||
if( x != static_cast<T>(a.x) )
|
||||
return true;
|
||||
|
||||
if( y != static_cast<T>(a.y) )
|
||||
return true;
|
||||
|
||||
if( z != static_cast<T>(a.z) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* return the length of the vector
|
||||
*/
|
||||
inline T length() const
|
||||
{
|
||||
return static_cast<T>( sqrt(x*x + y*y + z*z) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* length squared
|
||||
*/
|
||||
inline T length2() const
|
||||
{
|
||||
return x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* calculate the cross product
|
||||
*/
|
||||
template <class S>
|
||||
inline Vector3Template<T> cross(
|
||||
const Vector3Template<S> &a ) const
|
||||
{
|
||||
return Vector3Template<T>(
|
||||
y * static_cast<T>(a.z) - z * static_cast<T>(a.y),
|
||||
z * static_cast<T>(a.x) - x * static_cast<T>(a.z),
|
||||
x * static_cast<T>(a.y) - y * static_cast<T>(a.x)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* calculate dot product
|
||||
*/
|
||||
template <class S>
|
||||
inline T dot( const Vector3Template<S> &a ) const
|
||||
{
|
||||
return (
|
||||
x * static_cast<T>(a.x) +
|
||||
y * static_cast<T>(a.y) +
|
||||
z * static_cast<T>(a.z) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* check if vectors are nearly equal
|
||||
*/
|
||||
template <class S>
|
||||
inline bool nearlyEquals(
|
||||
const Vector3Template<S> &a,
|
||||
T epsilon = 0.00001 ) const
|
||||
{
|
||||
if( fabs(x-static_cast<T>(a.x)) > epsilon )
|
||||
return false;
|
||||
|
||||
if( fabs(y-static_cast<T>(a.y)) > epsilon )
|
||||
return false;
|
||||
|
||||
if( fabs(z-static_cast<T>(a.z)) > epsilon )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* normalize the vector to length 1
|
||||
*/
|
||||
inline void normalize()
|
||||
{
|
||||
T a = length();
|
||||
if( a == 0 )
|
||||
return;
|
||||
|
||||
x /= a;
|
||||
y /= a;
|
||||
z /= a;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get normalized vector
|
||||
*/
|
||||
inline Vector3Template<T> normalized() const
|
||||
{
|
||||
T a = length();
|
||||
if( a == 0 )
|
||||
return Vector3Template<T>( 0.0, 0.0, 1.0 );
|
||||
return Vector3Template<T>( x / a, y / a, z / a );
|
||||
}
|
||||
|
||||
/**
|
||||
* check if vectors are parallel
|
||||
*/
|
||||
inline bool parallel( const Vector3Template<T> &a ) const
|
||||
{
|
||||
return ( (static_cast<T>(a.x) / x) ==
|
||||
(static_cast<T>(a.y) / y) ==
|
||||
(static_cast<T>(a.z) / z) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* check if vectors are parallel
|
||||
*/
|
||||
template <class S>
|
||||
inline bool nearlyParallel(
|
||||
const Vector3Template<S> &a,
|
||||
T epsilon = 0.00001 ) const
|
||||
{
|
||||
T ax = static_cast<T>(a.x) / x;
|
||||
T ay = static_cast<T>(a.y) / y;
|
||||
T az = static_cast<T>(a.z) / z;
|
||||
|
||||
if( fabs(ax - ay) > epsilon )
|
||||
return false;
|
||||
|
||||
if( fabs(ax - az) > epsilon )
|
||||
return false;
|
||||
|
||||
if( fabs(ay - az) > epsilon )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if vectors are orthogonal
|
||||
*/
|
||||
inline bool orthogonal( const Vector3Template<T> &a ) const
|
||||
{
|
||||
return ( dot(a) == static_cast<T>(0) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* check if vectors are orthogonal
|
||||
*/
|
||||
template <class S>
|
||||
inline bool nearlyOrthogonal(
|
||||
const Vector3Template<S> &a,
|
||||
T epsilon = 0.00001 ) const
|
||||
{
|
||||
return ( dot(a) < epsilon );
|
||||
}
|
||||
|
||||
T& operator[] (unsigned int i)
|
||||
{
|
||||
if( i == 0 )
|
||||
return x;
|
||||
else if( i == 1 )
|
||||
return y;
|
||||
else if( i == 2 )
|
||||
return z;
|
||||
else
|
||||
throw "index out of bound";
|
||||
}
|
||||
|
||||
friend std::ostream &operator << ( std::ostream& os, Vector3Template<T> v )
|
||||
{
|
||||
os << "( " << v.x << ", " << v.y << ", " << v.z << " )";
|
||||
return os;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef Vector3Template<float> Vector3Float;
|
||||
typedef Vector3Template<double> Vector3Double;
|
||||
typedef Vector3Template<Scalar> Vector3;
|
||||
}
|
||||
|
||||
#endif
|
419
engine/MeshManager.cpp
Normal file
419
engine/MeshManager.cpp
Normal file
@ -0,0 +1,419 @@
|
||||
#include "MeshManager.h"
|
||||
|
||||
#include "Utilities/format.h"
|
||||
#include "Utilities/Log.h"
|
||||
|
||||
#include "physfs.h"
|
||||
#include "trimeshloader.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Mesh::Mesh(RenderDevice* device) :
|
||||
_Device(device)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Mesh::~Mesh()
|
||||
{
|
||||
clog << ">>> Mesh destructed ..."<< endline;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Mesh::render()
|
||||
{
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
glVertexPointer( 3, GL_FLOAT, sizeof(Vertex), &VertexBuffer[0].point.x);
|
||||
|
||||
glTexCoordPointer( 2, GL_FLOAT, sizeof(Vertex), &VertexBuffer[0].u);
|
||||
|
||||
glNormalPointer(GL_FLOAT, sizeof(Vertex), &VertexBuffer[0].normal.x);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, IndexBuffer.count() * 3, GL_UNSIGNED_SHORT,
|
||||
IndexBuffer.data() );
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
||||
#if 0
|
||||
//--------------------------------------------------------------------------
|
||||
void Mesh::createVBO()
|
||||
{
|
||||
if ( GLEW_ARB_vertex_buffer_object && !vbo )
|
||||
{
|
||||
glGenBuffersARB ( 1, &vbo );
|
||||
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo );
|
||||
|
||||
glBufferDataARB (
|
||||
GL_ARRAY_BUFFER_ARB,
|
||||
size(),
|
||||
data(),
|
||||
GL_STATIC_DRAW_ARB );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Mesh::releaseVBO()
|
||||
{
|
||||
if ( GLEW_ARB_vertex_buffer_object && vbo )
|
||||
{
|
||||
glDeleteBuffersARB ( 1, &vbo );
|
||||
vbo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Mesh::bind()
|
||||
{
|
||||
if ( GLEW_ARB_vertex_buffer_object && vbo )
|
||||
{
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo );
|
||||
|
||||
// hardcoded offset and stride
|
||||
glVertexPointer ( 3, GL_FLOAT, sizeof ( Vertex ), 0 );
|
||||
|
||||
glTexCoordPointer ( 2, GL_FLOAT, sizeof ( Vertex ), ( const GLvoid* ) ( sizeof ( float ) * 3 ) );
|
||||
|
||||
glNormalPointer ( GL_FLOAT, sizeof ( Vertex ), ( const GLvoid* ) ( sizeof ( float ) * 5 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// hardcoded offset and stride
|
||||
glVertexPointer ( 3, GL_FLOAT, sizeof ( Vertex ), data() );
|
||||
glTexCoordPointer ( 2, GL_FLOAT, sizeof ( Vertex ), data() + sizeof ( float ) * 3 );
|
||||
glNormalPointer ( GL_FLOAT, sizeof ( Vertex ), data() + sizeof ( float ) * 5 );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
MeshManager::MeshManager(RenderDevice* device) :
|
||||
_Device(device)
|
||||
{
|
||||
BlueCore::clog << ">>> MeshManager constructed..." << endlog;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
MeshManager::~MeshManager()
|
||||
{
|
||||
clog << ">>> MeshManager destructed ..." << endlog;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool loadTrimesh(const char* filename, Mesh *mesh)
|
||||
{
|
||||
PHYSFS_file* file = PHYSFS_openRead(filename);
|
||||
if (file != 0)
|
||||
{
|
||||
char buffer[1024];
|
||||
unsigned int size = 0;
|
||||
|
||||
if (tlObjCheckFileExtension(filename) == 0)
|
||||
{
|
||||
tlObjState *state = tlObjCreateState();
|
||||
while (PHYSFS_eof(file) == 0)
|
||||
{
|
||||
size = (unsigned int) PHYSFS_read(file, buffer, 1,
|
||||
sizeof(buffer));
|
||||
tlObjParse(state, buffer, size, size < sizeof(buffer) ? 1 : 0);
|
||||
}
|
||||
|
||||
mesh->VertexBuffer.create(tlObjVertexCount(state));
|
||||
for (unsigned int i = 0; i < mesh->VertexBuffer.count(); i++)
|
||||
tlObjGetVertex(state, i, &mesh->VertexBuffer[i].point.x,
|
||||
&mesh->VertexBuffer[i].point.y,
|
||||
&mesh->VertexBuffer[i].point.z,
|
||||
&mesh->VertexBuffer[i].u, &mesh->VertexBuffer[i].v,
|
||||
&mesh->VertexBuffer[i].normal.x,
|
||||
&mesh->VertexBuffer[i].normal.y,
|
||||
&mesh->VertexBuffer[i].normal.z);
|
||||
|
||||
mesh->IndexBuffer.create(tlObjFaceCount(state));
|
||||
for (unsigned int i = 0; i < mesh->IndexBuffer.count(); i++)
|
||||
tlObjGetFace(state, i, &mesh->IndexBuffer[i].a,
|
||||
&mesh->IndexBuffer[i].b, &mesh->IndexBuffer[i].c);
|
||||
|
||||
mesh->SubsetBuffer.create(tlObjObjectCount(state));
|
||||
for (unsigned int i = 0; i < mesh->SubsetBuffer.count(); i++)
|
||||
{
|
||||
mesh->SubsetBuffer[i].first = tlObjObjectFaceIndex(state, i);
|
||||
mesh->SubsetBuffer[i].count = tlObjObjectFaceCount(state, i);
|
||||
}
|
||||
|
||||
tlObjDestroyState(state);
|
||||
}
|
||||
else if (tl3dsCheckFileExtension(filename) == 0)
|
||||
{
|
||||
tl3dsState *state = tl3dsCreateState();
|
||||
while (PHYSFS_eof(file) == 0)
|
||||
{
|
||||
size = (unsigned int) PHYSFS_read(file, buffer, 1,
|
||||
sizeof(buffer));
|
||||
tl3dsParse(state, buffer, size, size < sizeof(buffer) ? 1 : 0);
|
||||
}
|
||||
|
||||
mesh->VertexBuffer.create(tl3dsVertexCount(state));
|
||||
for (unsigned int i = 0; i < mesh->VertexBuffer.count(); i++)
|
||||
tl3dsGetVertex(state, i, &mesh->VertexBuffer[i].point.x,
|
||||
&mesh->VertexBuffer[i].point.y,
|
||||
&mesh->VertexBuffer[i].point.z,
|
||||
&mesh->VertexBuffer[i].u, &mesh->VertexBuffer[i].v,
|
||||
&mesh->VertexBuffer[i].normal.x,
|
||||
&mesh->VertexBuffer[i].normal.y,
|
||||
&mesh->VertexBuffer[i].normal.z);
|
||||
|
||||
mesh->IndexBuffer.create(tl3dsFaceCount(state));
|
||||
for (unsigned int i = 0; i < mesh->IndexBuffer.count(); i++)
|
||||
tl3dsGetFace(state, i, &mesh->IndexBuffer[i].a,
|
||||
&mesh->IndexBuffer[i].b, &mesh->IndexBuffer[i].c);
|
||||
|
||||
mesh->SubsetBuffer.create(tl3dsObjectCount(state));
|
||||
for (unsigned int i = 0; i < mesh->SubsetBuffer.count(); i++)
|
||||
{
|
||||
mesh->SubsetBuffer[i].first = tl3dsObjectFaceIndex(state, i);
|
||||
mesh->SubsetBuffer[i].count = tl3dsObjectFaceCount(state, i);
|
||||
}
|
||||
|
||||
tl3dsDestroyState(state);
|
||||
}
|
||||
|
||||
PHYSFS_close(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Mesh *MeshManager::loadMesh(const string &filename)
|
||||
{
|
||||
// check if this mesh is already loaded
|
||||
std::map<std::string, weak_ptr<Mesh> >::const_iterator result;
|
||||
result = _Meshes.find(filename);
|
||||
|
||||
if (result != _Meshes.end() && result->second.valid())
|
||||
{
|
||||
return result->second.get();
|
||||
}
|
||||
|
||||
Mesh *mesh = new Mesh (_Device.get());
|
||||
|
||||
// check cache
|
||||
PHYSFS_sint64 mod_file = PHYSFS_getLastModTime(filename.c_str());
|
||||
|
||||
std::string cachename = filename + ".msc";
|
||||
PHYSFS_sint64 mod_cache = PHYSFS_getLastModTime(cachename.c_str());
|
||||
|
||||
if ( (mod_cache > mod_file) && loadFromCache(mesh, filename) )
|
||||
{
|
||||
clog << ">>> Mesh '" << filename << "' loaded from cache." << endline;
|
||||
|
||||
_Meshes[filename] = mesh;
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
clog << ">>> Mesh '" << filename << "': loading from file..." << endlog;
|
||||
|
||||
if (loadTrimesh(filename.c_str(), mesh) != 0)
|
||||
{
|
||||
mesh->removeReference();
|
||||
clog << "!!! Mesh not found!" << endline;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
mesh->buildShadowFaceBuffer();
|
||||
mesh->buildTangentBuffer();
|
||||
|
||||
unsigned int counter;
|
||||
|
||||
// calculate bounding sphere
|
||||
clog << " calculate bounding sphere";
|
||||
|
||||
mesh->bounding_sphere.center().zero();
|
||||
|
||||
for ( counter = 0; counter < mesh->vertex_buffer.count(); counter++ )
|
||||
{
|
||||
mesh->bounding_sphere.center() += mesh->vertex_buffer[counter].point;
|
||||
}
|
||||
|
||||
mesh->bounding_sphere.center() /= mesh->vertex_buffer.size();
|
||||
|
||||
mesh->bounding_sphere.radius() = 0.;
|
||||
|
||||
for ( counter = 0; counter < mesh->vertex_buffer.count(); counter++ )
|
||||
{
|
||||
Scalar distance = ( mesh->vertex_buffer[counter].point - mesh->bounding_sphere.center() ).length();
|
||||
|
||||
if ( distance > mesh->bounding_sphere.radius() )
|
||||
mesh->bounding_sphere.radius() = distance;
|
||||
}
|
||||
|
||||
clog << ": " << mesh->bounding_sphere.radius() << endline;
|
||||
|
||||
// create normlas, tangents, and binomials
|
||||
clog << " create normlas, tangents, and binomials" << endline;
|
||||
|
||||
for ( counter = 0; counter < mesh->vertex_buffer.count(); counter += 1 )
|
||||
{
|
||||
mesh->vertex_buffer[counter].normal.zero();
|
||||
}
|
||||
|
||||
for ( counter = 0; counter < mesh->index_buffer.count(); counter += 3 )
|
||||
{
|
||||
Index a = mesh->index_buffer[counter];
|
||||
Index b = mesh->index_buffer[counter+1];
|
||||
Index c = mesh->index_buffer[counter+2];
|
||||
|
||||
Vector3Template<float> ab = mesh->vertex_buffer[ a ].point - mesh->vertex_buffer[ b ].point;
|
||||
Vector3Template<float> ac = mesh->vertex_buffer[ a ].point - mesh->vertex_buffer[ c ].point;
|
||||
Vector3Template<float> n = ab.cross ( ac );
|
||||
|
||||
mesh->vertex_buffer[ a ].normal += n;
|
||||
mesh->vertex_buffer[ b ].normal += n;
|
||||
mesh->vertex_buffer[ c ].normal += n;
|
||||
}
|
||||
|
||||
for ( counter = 0; counter < mesh->vertex_buffer.count(); counter += 1 )
|
||||
{
|
||||
mesh->vertex_buffer[counter].normal.normalize();
|
||||
}
|
||||
|
||||
clog << " create vbos" << endline;
|
||||
|
||||
mesh->vertex_buffer.createVBO();
|
||||
mesh->index_buffer.createVBO();
|
||||
mesh->tangent_buffer.createVBO();
|
||||
mesh->bitangent_buffer.createVBO();
|
||||
#endif
|
||||
|
||||
_Meshes[filename] = mesh;
|
||||
|
||||
saveToCache(mesh, filename);
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool MeshManager::loadFromCache(Mesh *mesh, const std::string &name)
|
||||
{
|
||||
std::string filename = name + ".msc";
|
||||
|
||||
PHYSFS_file *file = PHYSFS_openRead(filename.c_str());
|
||||
|
||||
if (file == 0)
|
||||
return false;
|
||||
|
||||
unsigned int size;
|
||||
|
||||
// read vertex_buffer
|
||||
PHYSFS_read(file, &size, sizeof (size ), 1);
|
||||
mesh->VertexBuffer.create(size);
|
||||
PHYSFS_read(file, mesh->VertexBuffer.data(), mesh->VertexBuffer.size(), 1);
|
||||
|
||||
// read index buffer
|
||||
PHYSFS_read(file, &size, sizeof (size ), 1);
|
||||
mesh->IndexBuffer.create(size);
|
||||
PHYSFS_read(file, mesh->IndexBuffer.data(), mesh->IndexBuffer.size(), 1);
|
||||
#if 0
|
||||
// read tangent buffer
|
||||
PHYSFS_read ( file, &size, sizeof ( size ), 1 );
|
||||
mesh->tangent_buffer.create ( size );
|
||||
PHYSFS_read ( file, mesh->tangent_buffer.data(), mesh->tangent_buffer.size(), 1 );
|
||||
|
||||
// read bitangent buffer
|
||||
PHYSFS_read ( file, &size, sizeof ( size ), 1 );
|
||||
mesh->bitangent_buffer.create ( size );
|
||||
PHYSFS_read ( file, mesh->bitangent_buffer.data(), mesh->bitangent_buffer.size(), 1 );
|
||||
|
||||
// read bounding sphere
|
||||
PHYSFS_read ( file, &mesh->bounding_sphere, sizeof ( mesh->bounding_sphere ), 1 );
|
||||
#endif
|
||||
|
||||
// read subsets
|
||||
PHYSFS_read(file, &size, sizeof (size ), 1);
|
||||
mesh->SubsetBuffer.create(size);
|
||||
PHYSFS_read(file, mesh->SubsetBuffer.data(), mesh->SubsetBuffer.size(), 1);
|
||||
#if 0
|
||||
// read bitangent buffer
|
||||
PHYSFS_read ( file, &size, sizeof ( size ), 1 );
|
||||
mesh->shadowface_buffer.create ( size );
|
||||
PHYSFS_read ( file, mesh->shadowface_buffer.data(), mesh->shadowface_buffer.size(), 1 );
|
||||
#endif
|
||||
|
||||
PHYSFS_close(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool MeshManager::saveToCache(Mesh *mesh, const std::string &name)
|
||||
|
||||
{
|
||||
std::string filename = name + ".msc";
|
||||
|
||||
PHYSFS_file *file = PHYSFS_openWrite(filename.c_str() );
|
||||
|
||||
if (file == 0)
|
||||
{
|
||||
clog << ">>> cannot open cache file for mesh: " << name << endline;
|
||||
return false;
|
||||
}
|
||||
|
||||
// write vertex_buffer
|
||||
unsigned int size = mesh->VertexBuffer.count();
|
||||
PHYSFS_write(file, &size, sizeof (size ), 1);
|
||||
PHYSFS_write(file, mesh->VertexBuffer.data(), mesh->VertexBuffer.size(), 1);
|
||||
|
||||
// write index_buffer
|
||||
size = mesh->IndexBuffer.count();
|
||||
PHYSFS_write(file, &size, sizeof (size ), 1);
|
||||
PHYSFS_write(file, mesh->IndexBuffer.data(), mesh->IndexBuffer.size(), 1);
|
||||
|
||||
// write subsets
|
||||
size = mesh->SubsetBuffer.count();
|
||||
PHYSFS_write(file, &size, sizeof (size ), 1);
|
||||
PHYSFS_write(file, mesh->SubsetBuffer.data(), mesh->SubsetBuffer.size(), 1);
|
||||
|
||||
#if 0
|
||||
// write tangent_buffer
|
||||
size = mesh->tangent_buffer.count();
|
||||
PHYSFS_write ( file, &size, sizeof ( size ), 1 );
|
||||
PHYSFS_write ( file, mesh->tangent_buffer.data(), mesh->tangent_buffer.size(), 1 );
|
||||
|
||||
// write bitangent_buffer
|
||||
size = mesh->bitangent_buffer.count();
|
||||
PHYSFS_write ( file, &size, sizeof ( size ), 1 );
|
||||
PHYSFS_write ( file, mesh->bitangent_buffer.data(), mesh->bitangent_buffer.size(), 1 );
|
||||
|
||||
// write bounding sphere
|
||||
PHYSFS_write ( file, &mesh->bounding_sphere, sizeof ( mesh->bounding_sphere ), 1 );
|
||||
|
||||
// write shadowfaces
|
||||
size = mesh->shadowface_buffer.count();
|
||||
PHYSFS_write ( file, &size, sizeof ( size ), 1 );
|
||||
PHYSFS_write ( file, mesh->shadowface_buffer.data(), mesh->shadowface_buffer.size(), 1 );
|
||||
#endif
|
||||
|
||||
PHYSFS_close(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace BlueCore
|
94
engine/MeshManager.h
Normal file
94
engine/MeshManager.h
Normal file
@ -0,0 +1,94 @@
|
||||
#ifndef BLUECORE_MESH_MANAGER_H
|
||||
#define BLUECORE_MESH_MANAGER_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "RenderDevice.h"
|
||||
#include "Math/Vector.h"
|
||||
#include "Math/Plane.h"
|
||||
#include "Utilities/Buffer.h"
|
||||
#include "Utilities/Referenced.h"
|
||||
|
||||
namespace BlueCore {
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Vector3Float point;
|
||||
float u, v;
|
||||
Vector3Float normal;
|
||||
} Vertex;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short a, b, c;
|
||||
} TriangleIndices;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
public:
|
||||
unsigned int first;
|
||||
unsigned int count;
|
||||
} Subset;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short neighbours[3];
|
||||
PlaneFloat plane;
|
||||
bool backFace;
|
||||
} ShadowFace;
|
||||
|
||||
class Mesh : public Referenced
|
||||
{
|
||||
|
||||
ref_ptr<RenderDevice> _Device;
|
||||
|
||||
public:
|
||||
|
||||
Buffer<Vertex> VertexBuffer;
|
||||
Buffer<TriangleIndices> IndexBuffer;
|
||||
Buffer<Subset> SubsetBuffer;
|
||||
|
||||
Buffer<Vector3Float> tangents;
|
||||
Buffer<Vector3Float> bitangents;
|
||||
Buffer<ShadowFace> shadowfaces;
|
||||
|
||||
public:
|
||||
|
||||
Mesh (RenderDevice* device);
|
||||
|
||||
void render ();
|
||||
void upload ();
|
||||
|
||||
protected:
|
||||
|
||||
~Mesh();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class MeshManager : public Referenced
|
||||
{
|
||||
private:
|
||||
|
||||
std::map<std::string, weak_ptr<Mesh> > _Meshes;
|
||||
|
||||
bool saveToCache ( Mesh *mesh, const std::string &name );
|
||||
|
||||
bool loadFromCache ( Mesh *mesh, const std::string &name );
|
||||
|
||||
ref_ptr<RenderDevice> _Device;
|
||||
|
||||
public:
|
||||
|
||||
MeshManager (RenderDevice *device);
|
||||
|
||||
~MeshManager();
|
||||
|
||||
Mesh *loadMesh (const std::string &name);
|
||||
};
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif
|
322
engine/ModelManager.cpp
Normal file
322
engine/ModelManager.cpp
Normal file
@ -0,0 +1,322 @@
|
||||
#include "ModelManager.h"
|
||||
|
||||
#include "MeshManager.h"
|
||||
#include "ShaderManager.h"
|
||||
|
||||
#include "Utilities/StringUtilities.h"
|
||||
#include "Utilities/Log.h"
|
||||
|
||||
#include "tinyxml.h"
|
||||
#include "physfs.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Model::render()
|
||||
{
|
||||
ModelMesh->render();
|
||||
//glEnable(GL_LIGHTING);
|
||||
//glDepthFunc ( GL_LEQUAL );
|
||||
//glEnable ( GL_DEPTH_TEST );
|
||||
//glDepthMask ( GL_TRUE );
|
||||
|
||||
/*
|
||||
glEnableClientState (GL_VERTEX_ARRAY );
|
||||
glEnableClientState (GL_TEXTURE_COORD_ARRAY );
|
||||
glEnableClientState (GL_NORMAL_ARRAY );
|
||||
|
||||
glMatrixMode (GL_MODELVIEW );
|
||||
glPushMatrix();
|
||||
Matrix4x4 m(_AbsoluteRotation, _AbsoluteTranslation);
|
||||
glMultMatrixd ( ( GLdouble * ) &m.m );
|
||||
|
||||
mesh->vertex_buffer.bind();
|
||||
mesh->index_buffer.bind();
|
||||
*/
|
||||
/*
|
||||
glMaterialfv (GL_FRONT, GL_SHININESS, &pass.Shininess);
|
||||
glMaterialfv (GL_FRONT, GL_SPECULAR, ( GLfloat * ) &pass.Specular );
|
||||
|
||||
// setup shader
|
||||
if (pass.Program && ShaderManager::getSingleton()->usingShaders() )
|
||||
{
|
||||
ShaderManager::getSingleton()->useShaderProgram(pass.Program);
|
||||
|
||||
int textureId = 0;
|
||||
std::vector<Model::TextureUnit>::iterator titer;
|
||||
|
||||
for (titer = pass.Textures.begin(); titer != pass.Textures.end(); titer++)
|
||||
{
|
||||
Renderer::getSingleton()->bindTexture(( *titer ).mTexture, textureId );
|
||||
ShaderManager::getSingleton()->useTexture(pass.Program, textureId, ( *titer ).mName);
|
||||
textureId++;
|
||||
}
|
||||
|
||||
if (pass.Tangents)
|
||||
{
|
||||
ShaderManager::getSingleton()->useTangentBuffer(pass.Program, &mesh->tangent_buffer, "tangent");
|
||||
ShaderManager::getSingleton()->useTangentBuffer(pass.Program, &mesh->bitangent_buffer,
|
||||
"bitangent");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glActiveTextureARB (GL_TEXTURE2_ARB );
|
||||
glDisable (GL_TEXTURE_2D );
|
||||
glActiveTextureARB (GL_TEXTURE1_ARB );
|
||||
glDisable (GL_TEXTURE_2D );
|
||||
int textureId = 0;
|
||||
|
||||
std::vector<Model::TextureUnit>::iterator titer;
|
||||
for (titer = pass.Textures.begin(); titer != pass.Textures.end(); titer++)
|
||||
{
|
||||
Renderer::getSingleton()->bindTexture(( *titer ).mTexture, textureId );
|
||||
ShaderManager::getSingleton()->useTexture(pass.Program, textureId, ( *titer ).mName);
|
||||
textureId++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// render subsets
|
||||
SubsetVector::iterator iter;
|
||||
for (iter = mesh->surface_subsets.begin(); iter
|
||||
!= mesh->surface_subsets.end(); iter++)
|
||||
{
|
||||
Subset subset = *iter;
|
||||
mesh->index_buffer.draw(subset.first, subset.count);
|
||||
}
|
||||
|
||||
// cleanup
|
||||
if (pass.Program && ShaderManager::getSingleton()->usingShaders() )
|
||||
{
|
||||
ShaderManager::getSingleton()->useShaderProgram( 0);
|
||||
if (pass.Tangents)
|
||||
{
|
||||
ShaderManager::getSingleton()->disableTangentBuffer(pass.Program, "tangent");
|
||||
ShaderManager::getSingleton()->disableTangentBuffer(pass.Program, "bitangent");
|
||||
}
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glActiveTextureARB (GL_TEXTURE2_ARB );
|
||||
glDisable (GL_TEXTURE_2D );
|
||||
glActiveTextureARB (GL_TEXTURE1_ARB );
|
||||
glDisable (GL_TEXTURE_2D );
|
||||
glActiveTextureARB (GL_TEXTURE0_ARB );
|
||||
glDisable (GL_TEXTURE_2D );
|
||||
*/
|
||||
/*
|
||||
glDisableClientState (GL_VERTEX_ARRAY );
|
||||
glDisableClientState (GL_TEXTURE_COORD_ARRAY );
|
||||
glDisableClientState (GL_NORMAL_ARRAY );
|
||||
*/
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
ModelManager::ModelManager(TextureManager *texturemanager,
|
||||
ShaderManager* shadermanager, MeshManager* meshmanager) :
|
||||
_TextureManager(texturemanager), _ShaderManager(shadermanager),
|
||||
_MeshManager(meshmanager)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ModelManager::~ModelManager()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ModelManager::parseRenderPassDefinition(
|
||||
Model::RenderPassDefinition &Definition,
|
||||
const TiXmlElement* DefinitionElement)
|
||||
{
|
||||
|
||||
const TiXmlElement * TextureElement =
|
||||
DefinitionElement->FirstChildElement("Texture");
|
||||
|
||||
while (TextureElement)
|
||||
{
|
||||
Model::TextureUnit unit;
|
||||
unit.mName = TextureElement->Attribute("name");
|
||||
|
||||
const char *file = TextureElement->Attribute("file");
|
||||
|
||||
if (file)
|
||||
unit.mTexture = _TextureManager->loadTexture(file);
|
||||
else
|
||||
unit.mTexture = 0;
|
||||
|
||||
Definition.Textures.push_back(unit);
|
||||
|
||||
TextureElement = TextureElement->NextSiblingElement("Texture");
|
||||
}
|
||||
|
||||
const TiXmlElement * ShaderElement =
|
||||
DefinitionElement->FirstChildElement("Shader");
|
||||
|
||||
if (ShaderElement)
|
||||
{
|
||||
Definition.Program
|
||||
= _ShaderManager->loadShaderProgram(ShaderElement->Attribute("name") );
|
||||
|
||||
const char *t = ShaderElement->Attribute("tangents");
|
||||
if (t && string("true") == t)
|
||||
Definition.Tangents = true;
|
||||
else
|
||||
Definition.Tangents = false;
|
||||
}
|
||||
else
|
||||
Definition.Program = 0;
|
||||
|
||||
const TiXmlElement * MaterialElement =
|
||||
DefinitionElement->FirstChildElement("Material");
|
||||
|
||||
if (MaterialElement)
|
||||
{
|
||||
double s;
|
||||
MaterialElement->QueryDoubleAttribute("shininess", &s);
|
||||
Definition.Shininess = s;
|
||||
|
||||
std::vector<std::string> components;
|
||||
explode(MaterialElement->Attribute("specular"), components);
|
||||
|
||||
for (unsigned int i = 0; i < components.size(); i++)
|
||||
{
|
||||
Definition.Specular[i] = atof(components[i].c_str() );
|
||||
|
||||
if (i == 3)
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Definition.Enabled = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Model *ModelManager::loadModel(const string &name)
|
||||
{
|
||||
// check if this model is already loaded
|
||||
ModelContainer::const_iterator result;
|
||||
result = _Models.find(name);
|
||||
|
||||
if (result != _Models.end() )
|
||||
{
|
||||
return result->second.get();
|
||||
}
|
||||
|
||||
string filename = name + ".model.xml";
|
||||
// load the document
|
||||
PHYSFS_file *file = PHYSFS_openRead(filename.c_str());
|
||||
|
||||
if ( !file)
|
||||
{
|
||||
clog << "!!! XML-File '"<< name << "' not found"<< endline;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int fileSize = PHYSFS_fileLength(file);
|
||||
|
||||
Buffer<char> buffer(fileSize);
|
||||
|
||||
PHYSFS_read(file, buffer.data(), 1, buffer.size() );
|
||||
buffer[buffer.count() - 1] = 0;
|
||||
|
||||
PHYSFS_close(file);
|
||||
|
||||
TiXmlDocument *document = new TiXmlDocument();
|
||||
document->Parse(buffer.data() );
|
||||
|
||||
if (document->Error() )
|
||||
{
|
||||
clog << "!!! Error loading XML-File'"<< name << "': ";
|
||||
clog << document->ErrorRow() << ","<< document->ErrorCol();
|
||||
clog << " "<< document->ErrorDesc() << endline;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Model *model = new Model();
|
||||
|
||||
if (document == 0)
|
||||
{
|
||||
clog << "!!! Model '"<< name << "' not found!"<< endline;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const TiXmlElement *model_element = document->FirstChildElement("Model");
|
||||
|
||||
if (model_element)
|
||||
{
|
||||
const TiXmlElement* MeshElement =
|
||||
model_element->FirstChildElement("Mesh");
|
||||
|
||||
if (MeshElement)
|
||||
{
|
||||
model->ModelMesh
|
||||
= _MeshManager->loadMesh(MeshElement->Attribute("file") );
|
||||
}
|
||||
|
||||
const TiXmlElement * ShadowMeshElement =
|
||||
model_element->FirstChildElement("ShadowMesh");
|
||||
|
||||
if (ShadowMeshElement)
|
||||
{
|
||||
model->ShadowMesh
|
||||
= _MeshManager->loadMesh(ShadowMeshElement->Attribute("file") );
|
||||
}
|
||||
else
|
||||
{
|
||||
model->ShadowMesh = 0;
|
||||
}
|
||||
|
||||
const TiXmlElement* definition_element;
|
||||
|
||||
definition_element
|
||||
= model_element->FirstChildElement("AmbientRenderPass");
|
||||
if (definition_element)
|
||||
parseRenderPassDefinition(model->AmbientPass, definition_element);
|
||||
else
|
||||
model->AmbientPass.Enabled = false;
|
||||
|
||||
definition_element = model_element->FirstChildElement("LitRenderPass");
|
||||
if (definition_element)
|
||||
parseRenderPassDefinition(model->LitPass, definition_element);
|
||||
else
|
||||
model->LitPass.Enabled = false;
|
||||
|
||||
definition_element
|
||||
= model_element->FirstChildElement("DefaultRenderPass");
|
||||
if (definition_element)
|
||||
parseRenderPassDefinition(model->DefaultPass, definition_element);
|
||||
else
|
||||
model->DefaultPass.Enabled = false;
|
||||
|
||||
}
|
||||
|
||||
_Models[name] = model;
|
||||
|
||||
return model;
|
||||
}
|
||||
#if 0
|
||||
//------------------------------------------------------------------------------
|
||||
void ModelManager::unload()
|
||||
{
|
||||
ModelContainer::iterator iter;
|
||||
|
||||
for (iter = _Models.begin(); iter != _Models.end(); iter++)
|
||||
{
|
||||
clog << ">>> ModelManager: unload " << iter->first << endlog;
|
||||
|
||||
delete iter->second;
|
||||
}
|
||||
|
||||
_Models.clear();
|
||||
}
|
||||
#endif
|
||||
} // namespace BlueCore
|
80
engine/ModelManager.h
Normal file
80
engine/ModelManager.h
Normal file
@ -0,0 +1,80 @@
|
||||
#ifndef BLUECORE_MODEL_MANAGER_H
|
||||
#define BLUECORE_MODEL_MANAGER_H
|
||||
|
||||
// system includes
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
// project includes
|
||||
#include "Utilities/Referenced.h"
|
||||
#include "Utilities/Named.h"
|
||||
|
||||
#include "TextureManager.h"
|
||||
#include "ShaderManager.h"
|
||||
#include "MeshManager.h"
|
||||
|
||||
// forward declaration
|
||||
class TiXmlElement;
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
class Model : public Referenced, public Named
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
struct TextureUnit
|
||||
{
|
||||
std::string mName;
|
||||
ref_ptr<Texture> mTexture;
|
||||
};
|
||||
|
||||
struct RenderPassDefinition
|
||||
{
|
||||
bool Enabled;
|
||||
std::vector<TextureUnit> Textures;
|
||||
ShaderProgram Program;
|
||||
bool Tangents;
|
||||
float Shininess;
|
||||
float Specular[4];
|
||||
};
|
||||
|
||||
ref_ptr<Mesh> ModelMesh;
|
||||
ref_ptr<Mesh> ShadowMesh;
|
||||
RenderPassDefinition AmbientPass;
|
||||
RenderPassDefinition LitPass;
|
||||
RenderPassDefinition DefaultPass;
|
||||
|
||||
void render();
|
||||
};
|
||||
|
||||
class ModelManager : public Referenced
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef std::map< std::string, weak_ptr<Model> > ModelContainer;
|
||||
|
||||
ModelContainer _Models;
|
||||
weak_ptr<TextureManager> _TextureManager;
|
||||
weak_ptr<ShaderManager> _ShaderManager;
|
||||
weak_ptr<MeshManager> _MeshManager;
|
||||
|
||||
void parseRenderPassDefinition(Model::RenderPassDefinition &Definition,
|
||||
const TiXmlElement* DefinitionElement);
|
||||
|
||||
void unload();
|
||||
|
||||
public:
|
||||
|
||||
ModelManager(TextureManager *texturemanager, ShaderManager* shadermanager,
|
||||
MeshManager* meshmanager);
|
||||
~ModelManager();
|
||||
|
||||
Model *loadModel(const std::string &name);
|
||||
};
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif
|
26
engine/Node.h
Normal file
26
engine/Node.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef NODE_H_
|
||||
#define NODE_H_
|
||||
|
||||
class Node
|
||||
{
|
||||
class UpdateListener
|
||||
{
|
||||
virtual void update() = 0;
|
||||
virtual ~UpdateListener() = 0;
|
||||
};
|
||||
typedef std::list<Node*> NodeContainer;
|
||||
typedef std::list<Node*> NodeContainer;
|
||||
|
||||
Node *parent;
|
||||
NodeContainer children;
|
||||
|
||||
Vector3 getRelativePosition;
|
||||
Vector3 getAbsolutePosition;
|
||||
/* ... */
|
||||
|
||||
bool _Updating;
|
||||
void update (double time);
|
||||
void render (Camera *camera, RenderDevice *device);
|
||||
};
|
||||
|
||||
#endif /*NODE_H_*/
|
329
engine/RenderDevice.cpp
Normal file
329
engine/RenderDevice.cpp
Normal file
@ -0,0 +1,329 @@
|
||||
#include "RenderDevice.h"
|
||||
|
||||
#include "Utilities/Log.h"
|
||||
|
||||
#include "GL/gl.h"
|
||||
#include "GL/glu.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderDevice::WindowResizeSlot(int width, int height)
|
||||
{
|
||||
glViewport( 0, 0, width, height);
|
||||
_ViewportWidth = width;
|
||||
_ViewportHeight = height;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
RenderDevice::RenderDevice(RenderWindow* renderWindow) :
|
||||
_RenderWindow(renderWindow)
|
||||
{
|
||||
if (_RenderWindow.valid())
|
||||
{
|
||||
_RenderWindow->WindowResizeSignal.connect(this,
|
||||
&RenderDevice::WindowResizeSlot);
|
||||
|
||||
_RenderWindow->WindowCloseSignal.connect(this,
|
||||
&RenderDevice::WindowCloseSlot);
|
||||
|
||||
_ViewportWidth = _RenderWindow->getWidth();
|
||||
_ViewportHeight = _RenderWindow->getHeight();
|
||||
glViewport( 0, 0, _ViewportWidth, _ViewportHeight);
|
||||
}
|
||||
|
||||
clog << ">>> RenderDevice constructed..."<< endlog;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
RenderDevice::~RenderDevice()
|
||||
{
|
||||
clog << ">>> RenderDevice destructed..."<< endlog;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderDevice::WindowCloseSlot()
|
||||
{
|
||||
DeviceShutdownSignal();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int RenderDevice::getViewportWidth()
|
||||
{
|
||||
return _ViewportWidth;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int RenderDevice::getViewportHeight()
|
||||
{
|
||||
return _ViewportHeight;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderDevice::begin2D()
|
||||
{
|
||||
// prepare state
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glNormal3f( 0.0, 0.0, 1.0);
|
||||
|
||||
// set projection matrix
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
//int newheight = (_width / 16.0) * 9.0;
|
||||
gluOrtho2D( 0, _ViewportWidth-1, 0, _ViewportHeight-1);
|
||||
|
||||
// prepare model matrix
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderDevice::end2D()
|
||||
{
|
||||
// restore projection matrix
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
// restore model matrix
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
// restore old state
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderDevice::clear()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderDevice::setAmbientLight(float r, float g, float b)
|
||||
{
|
||||
GLfloat lightAmbient[] =
|
||||
{ r, g, b, 1.0f };
|
||||
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightAmbient);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
void RenderDevice::renderShadowVolume(Mesh *mesh,
|
||||
const Vector3Float &direction, const Vector3Float &extrude)
|
||||
{
|
||||
// Calculate visibility
|
||||
unsigned int i, frontface_count = 0;
|
||||
for (i=0; i < mesh->shadowfaces.count(); i++)
|
||||
{
|
||||
if (mesh->shadowfaces[i].plane.distance(extrude) < 0)
|
||||
{
|
||||
shadow_faces[i].backFace = false;
|
||||
frontface_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow_faces[i].backFace = true;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int max_edges = (frontface_count) * 3;
|
||||
if (_extrudeVertexBuffer.count() < (max_edges * 4))
|
||||
{
|
||||
clog << ">>> increase shadow buffers to "<< max_edges << " Edges"<< endline;
|
||||
_extrudeVertexBuffer.create( (max_edges + 100) * 4);
|
||||
}
|
||||
|
||||
if (_extrudeIndexBuffer.count() < (max_edges * 6))
|
||||
_extrudeIndexBuffer.create( (max_edges + 100) * 6);
|
||||
|
||||
// fill the buffer
|
||||
unsigned int j, k;
|
||||
extrude_quad_count = 0;
|
||||
Vertex *face_vertices[3];
|
||||
for (i=0; i<shadow_faces.count(); i++)
|
||||
{
|
||||
if (shadow_faces[i].backFace == false)
|
||||
{
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
k = shadow_faces[i].neighbours[j];
|
||||
if ( (k == 0) || (shadow_faces[k-1].backFace == true))
|
||||
{
|
||||
unsigned int src_index_offset = i * 3;
|
||||
face_vertices[0]
|
||||
= &mesh->vertex_buffer[ mesh->index_buffer[ src_index_offset ] ];
|
||||
face_vertices[1]
|
||||
= &mesh->vertex_buffer[ mesh->index_buffer[ src_index_offset + 1] ];
|
||||
face_vertices[2]
|
||||
= &mesh->vertex_buffer[ mesh->index_buffer[ src_index_offset + 2] ];
|
||||
|
||||
#ifdef DEBUG_SILHOUETTE
|
||||
glBegin( GL_LINES );
|
||||
glVertex3f( face_vertices[j]->point.x, face_vertices[j]->point.y, face_vertices[j]->point.z );
|
||||
glVertex3f( face_vertices[(j+1)%3]->point.x, face_vertices[(j+1)%3]->point.y, face_vertices[(j+1)%3]->point.z );
|
||||
glEnd();
|
||||
#endif
|
||||
|
||||
unsigned int vertex_offset = extrude_quad_count*4;
|
||||
_extrudeVertexBuffer[vertex_offset] = face_vertices[j]->point;
|
||||
_extrudeVertexBuffer[vertex_offset+1] = face_vertices[(j+1)%3]->point;
|
||||
_extrudeVertexBuffer[vertex_offset+2] = face_vertices[(j+1)%3]->point + extrude_vector;
|
||||
_extrudeVertexBuffer[vertex_offset+3] = face_vertices[j]->point
|
||||
+ extrude_vector;
|
||||
|
||||
unsigned int index_offset = extrude_quad_count*6;
|
||||
_extrudeIndexBuffer[index_offset] = vertex_offset;
|
||||
_extrudeIndexBuffer[index_offset+1] = vertex_offset + 3;
|
||||
_extrudeIndexBuffer[index_offset+2] = vertex_offset + 1;
|
||||
_extrudeIndexBuffer[index_offset+3] = vertex_offset + 1;
|
||||
_extrudeIndexBuffer[index_offset+4] = vertex_offset + 3;
|
||||
_extrudeIndexBuffer[index_offset+5] = vertex_offset + 2;
|
||||
|
||||
extrude_quad_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (_capIndexBuffer.count() < mesh->index_buffer.count() )
|
||||
_capIndexBuffer.create(mesh->index_buffer.count() );
|
||||
|
||||
bf = 0;
|
||||
ff = 0;
|
||||
|
||||
for (i=0; i<shadow_faces.count(); i++)
|
||||
{
|
||||
unsigned int dst_offset, src_offset = i*3;
|
||||
|
||||
if (shadow_faces[i].backFace == false)
|
||||
{
|
||||
dst_offset = ff*3;
|
||||
ff++;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_offset = _capIndexBuffer.count() - (bf + 1)*3;
|
||||
bf++;
|
||||
}
|
||||
|
||||
_capIndexBuffer[dst_offset] = mesh->index_buffer[src_offset];
|
||||
_capIndexBuffer[dst_offset+1] = mesh->index_buffer[src_offset+1];
|
||||
_capIndexBuffer[dst_offset+2] = mesh->index_buffer[src_offset+2];
|
||||
}
|
||||
|
||||
_lastOrientation = _AbsoluteRotation;
|
||||
}
|
||||
|
||||
if (_extrudeVertexBuffer.count() > 0)
|
||||
{
|
||||
// draw the volume
|
||||
glPushAttrib( GL_ALL_ATTRIB_BITS);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glEnable( GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
#if defined(DEBUG_SILHOUETTE) || defined(DEBUG_CAPS) || defined(DEBUG_VOLUME)
|
||||
glColorMask( 1, 1, 1, 1 );
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
#else
|
||||
glColorMask(0, 0, 0, 0);
|
||||
glDepthFunc(GL_LESS);
|
||||
#endif
|
||||
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_ALWAYS, 0, ~0);
|
||||
glStencilMask( ~0);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glMatrixMode ( GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
Matrix4x4 m(_AbsoluteRotation, _AbsoluteTranslation);
|
||||
glMultMatrixd ( ( GLdouble * ) &m.m );
|
||||
|
||||
glActiveTextureARB ( GL_TEXTURE2_ARB);
|
||||
glDisable ( GL_TEXTURE_2D);
|
||||
glActiveTextureARB ( GL_TEXTURE1_ARB);
|
||||
glDisable ( GL_TEXTURE_2D);
|
||||
glActiveTextureARB ( GL_TEXTURE0_ARB);
|
||||
glDisable ( GL_TEXTURE_2D);
|
||||
|
||||
ShaderManager::getSingleton()->useShaderProgram( 0);
|
||||
|
||||
#ifndef DEBUG_SILHOUETTE
|
||||
|
||||
glEnableClientState( GL_VERTEX_ARRAY);
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState( GL_NORMAL_ARRAY);
|
||||
glDisableClientState( GL_ARRAY_BUFFER_ARB);
|
||||
glDisableClientState( GL_ELEMENT_ARRAY_BUFFER_ARB);
|
||||
|
||||
for (int p=0; p<2; p++)
|
||||
{
|
||||
if (p==0)
|
||||
{
|
||||
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
|
||||
glCullFace(GL_FRONT);
|
||||
//glColorMask(0, 1, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
|
||||
glCullFace(GL_BACK);
|
||||
//glColorMask(1, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (GLEW_ARB_vertex_buffer_object )
|
||||
{
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, 0);
|
||||
glBindBufferARB ( GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
||||
}
|
||||
// #if !defined(DEBUG_CAPS) || defined(DEBUG_VOLUME)
|
||||
glVertexPointer ( 3, GL_FLOAT, 0, _extrudeVertexBuffer.data() );
|
||||
glDrawElements (
|
||||
GL_TRIANGLES,
|
||||
extrude_quad_count * 6,
|
||||
GL_UNSIGNED_SHORT,
|
||||
_extrudeIndexBuffer.data());
|
||||
// #endif
|
||||
|
||||
// #if !defined(DEBUG_VOLUME) || defined(DEBUG_CAPS)
|
||||
// draw caps
|
||||
mesh->vertex_buffer.bind();
|
||||
//glVertexPointer ( 3, GL_FLOAT, sizeof(Vertex), mesh->vertex_buffer.data() );
|
||||
glDrawElements (
|
||||
GL_TRIANGLES,
|
||||
ff*3,
|
||||
GL_UNSIGNED_SHORT,
|
||||
_capIndexBuffer.data());
|
||||
//&_capIndexBuffer[_capIndexBuffer.count() - bf*3]);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(extrude_vector.x, extrude_vector.y, extrude_vector.z);
|
||||
glDrawElements (
|
||||
GL_TRIANGLES,
|
||||
bf*3,
|
||||
GL_UNSIGNED_SHORT,
|
||||
&_capIndexBuffer[_capIndexBuffer.count() - bf*3]);
|
||||
//_capIndexBuffer.data() );
|
||||
glPopMatrix();
|
||||
// #endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
glPopAttrib();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
*/
|
||||
} // namespace BlueCore
|
58
engine/RenderDevice.h
Normal file
58
engine/RenderDevice.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef BLUECORE_RENDERDEVICE_H
|
||||
#define BLUECORE_RENDERDEVICE_H
|
||||
|
||||
#include "RenderWindow.h"
|
||||
|
||||
#include "Utilities/Buffer.h"
|
||||
#include "Utilities/Referenced.h"
|
||||
#include "Utilities/sigslot.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
class RenderDevice : public Referenced, public sigslot::has_slots<>
|
||||
{
|
||||
public:
|
||||
|
||||
class RenderItem
|
||||
{
|
||||
|
||||
public:
|
||||
//virtual void render ( RenderPass pass ) = 0;
|
||||
virtual ~RenderItem()
|
||||
{};
|
||||
};
|
||||
|
||||
private:
|
||||
int _ViewportWidth, _ViewportHeight;
|
||||
|
||||
void WindowResizeSlot(int width, int height);
|
||||
void WindowCloseSlot();
|
||||
|
||||
ref_ptr<RenderWindow> _RenderWindow;
|
||||
|
||||
public:
|
||||
|
||||
RenderDevice(RenderWindow* renderWindow);
|
||||
~RenderDevice();
|
||||
|
||||
int getViewportWidth();
|
||||
int getViewportHeight();
|
||||
|
||||
void begin2D();
|
||||
void end2D();
|
||||
|
||||
void clear();
|
||||
|
||||
void setAmbientLight(float r, float g, float b);
|
||||
|
||||
void setTexture(unsigned int unit, unsigned int texture);
|
||||
|
||||
sigslot::signal0<> DeviceShutdownSignal;
|
||||
|
||||
//Buffer<ShadowFace> &_ShadowFaces;
|
||||
};
|
||||
|
||||
} // namespaced BlueCore
|
||||
|
||||
#endif // BLUECORE_RENDERDEVICE_H
|
176
engine/RenderWindow.cpp
Normal file
176
engine/RenderWindow.cpp
Normal file
@ -0,0 +1,176 @@
|
||||
#include "RenderWindow.h"
|
||||
|
||||
#include "Utilities/Log.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
static RenderWindow* gRenderWindow = 0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
RenderWindow::RenderWindow() :
|
||||
_Initialized(false)
|
||||
{
|
||||
glfwInit();
|
||||
gRenderWindow = this;
|
||||
clog << ">>> RenderWindow constructed..."<< endlog;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
RenderWindow::~RenderWindow()
|
||||
{
|
||||
destroy();
|
||||
glfwTerminate();
|
||||
gRenderWindow = 0;
|
||||
clog << ">>> RenderWindow destructed..."<< endlog;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderWindow::WindowRefreshCallback()
|
||||
{
|
||||
gRenderWindow->WindowRefreshSignal();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int RenderWindow::WindowCloseCallback()
|
||||
{
|
||||
clog << ">>> RenderWindow closed..."<< endlog;
|
||||
gRenderWindow->closeWindow();
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderWindow::closeWindow()
|
||||
{
|
||||
_Closed = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderWindow::WindowSizeCallback(int width, int height)
|
||||
{
|
||||
gRenderWindow->resizeWindow(width, height);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderWindow::resizeWindow(int width, int height)
|
||||
{
|
||||
_Resized = true;
|
||||
|
||||
if ( !_Initialized)
|
||||
return;
|
||||
|
||||
clog << ">>> RenderWindow resized: "<< width << "x"<< height << endlog;
|
||||
|
||||
_Width = width;
|
||||
_Height = height;
|
||||
|
||||
WindowResizeSignal(width, height);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int RenderWindow::getWidth()
|
||||
{
|
||||
return _Width;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int RenderWindow::getHeight()
|
||||
{
|
||||
return _Height;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool RenderWindow::create(int width, int height, int pixelbits, int depthbits,
|
||||
int stencilbits, bool fullscreen)
|
||||
{
|
||||
int channelbits = 8;
|
||||
if (pixelbits == 16)
|
||||
channelbits = 4;
|
||||
|
||||
if (glfwOpenWindow(width, height, channelbits, channelbits, channelbits,
|
||||
channelbits, depthbits, stencilbits, fullscreen ? GLFW_FULLSCREEN
|
||||
: GLFW_WINDOW) == GL_FALSE)
|
||||
return false;
|
||||
|
||||
glfwSetWindowSizeCallback(WindowSizeCallback);
|
||||
glfwSetWindowCloseCallback(WindowCloseCallback);
|
||||
glfwSetWindowRefreshCallback(WindowRefreshCallback);
|
||||
|
||||
glfwSetMousePosCallback(MousePosCallback);
|
||||
glfwSetMouseButtonCallback(MouseButtonCallback);
|
||||
glfwSetMouseWheelCallback(MouseWheelCallback);
|
||||
glfwSetKeyCallback(KeyCallback);
|
||||
glfwSetCharCallback(CharCallback);
|
||||
|
||||
clog << ">>> RenderWindow created"<< endlog;
|
||||
|
||||
_Initialized = true;
|
||||
|
||||
glfwGetWindowSize( &_Width, &_Height);
|
||||
resizeWindow(_Width, _Height);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderWindow::swap()
|
||||
{
|
||||
glfwSwapBuffers();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderWindow::destroy()
|
||||
{
|
||||
if (_Initialized)
|
||||
{
|
||||
glfwCloseWindow();
|
||||
clog << ">>> RenderWindow destroyed"<< endlog;
|
||||
_Initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool RenderWindow::isOpen()
|
||||
{
|
||||
if (_Initialized == false)
|
||||
return false;
|
||||
|
||||
if (_Closed)
|
||||
return false;
|
||||
|
||||
return (glfwGetWindowParam(GLFW_OPENED) == GL_TRUE);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderWindow::MousePosCallback(int x, int y)
|
||||
{
|
||||
gRenderWindow->MouseMoveSignal(x, y);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderWindow::MouseButtonCallback(int button, int action)
|
||||
{
|
||||
gRenderWindow->MouseButtonSignal(button, action);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderWindow::MouseWheelCallback(int pos)
|
||||
{
|
||||
gRenderWindow->MouseWheelSignal(pos);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderWindow::KeyCallback(int key, int action)
|
||||
{
|
||||
gRenderWindow->KeySignal(key, action);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RenderWindow::CharCallback(int character, int action)
|
||||
{
|
||||
gRenderWindow->CharSignal(character);
|
||||
}
|
||||
|
||||
} // namespace BlueCore
|
71
engine/RenderWindow.h
Normal file
71
engine/RenderWindow.h
Normal file
@ -0,0 +1,71 @@
|
||||
#ifndef BLUECORE_RENDER_WINDOW_H
|
||||
#define BLUECORE_RENDER_WINDOW_H
|
||||
|
||||
// system includes
|
||||
#include <vector>
|
||||
|
||||
// library includes
|
||||
#include "GL/glfw.h"
|
||||
|
||||
// project includes
|
||||
#include "Math/Vector.h"
|
||||
#include "Utilities/sigslot.h"
|
||||
#include "Utilities/Referenced.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
class RenderWindow : public Referenced
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
static void WindowSizeCallback(int width, int height);
|
||||
static int WindowCloseCallback();
|
||||
static void WindowRefreshCallback();
|
||||
|
||||
static void MousePosCallback(int x, int y);
|
||||
static void MouseButtonCallback(int button, int action);
|
||||
static void MouseWheelCallback(int pos);
|
||||
static void KeyCallback(int key, int action);
|
||||
static void CharCallback(int character, int action);
|
||||
|
||||
bool _Resized;
|
||||
bool _Initialized;
|
||||
bool _Closed;
|
||||
int _Width, _Height;
|
||||
|
||||
void resizeWindow(int width, int height);
|
||||
|
||||
public:
|
||||
|
||||
sigslot::signal0<> WindowCloseSignal;
|
||||
sigslot::signal2<int, int> WindowResizeSignal;
|
||||
sigslot::signal0<> WindowRefreshSignal;
|
||||
|
||||
sigslot::signal2<int, int> MouseMoveSignal;
|
||||
sigslot::signal2<int, int> MouseButtonSignal;
|
||||
sigslot::signal1<int> MouseWheelSignal;
|
||||
sigslot::signal2<int, int> KeySignal;
|
||||
sigslot::signal1<int> CharSignal;
|
||||
|
||||
public:
|
||||
|
||||
RenderWindow();
|
||||
~RenderWindow();
|
||||
|
||||
bool create(int width, int height, int pixelbits, int depthbits,
|
||||
int stencilbits, bool fullscreen);
|
||||
|
||||
void destroy();
|
||||
void closeWindow();
|
||||
int getWidth();
|
||||
int getHeight();
|
||||
|
||||
bool isOpen();
|
||||
|
||||
void swap();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
618
engine/RigidBodySimulation.cpp
Normal file
618
engine/RigidBodySimulation.cpp
Normal file
@ -0,0 +1,618 @@
|
||||
#include "RigidBodySimulation.h"
|
||||
|
||||
// local includes
|
||||
//#include "scriptsystem.h"
|
||||
|
||||
// library includes
|
||||
#include "Utilities/StringUtilities.h"
|
||||
#include "Utilities/Log.h"
|
||||
//#include "Utilities/xmlconfig.h"
|
||||
|
||||
// system includes
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
static RigidBodySimulation* gRigidBodySimulation;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
RigidBody::RigidBody(RigidBodySimulation* simulation, dWorldID world,
|
||||
dSpaceID space) :
|
||||
_Body( 0), _Space( 0), _Simulation(simulation)
|
||||
{
|
||||
_Body = dBodyCreate(world);
|
||||
_Space = dHashSpaceCreate(space);
|
||||
dHashSpaceSetLevels(_Space, -10, 10);
|
||||
dBodySetData(_Body, this);
|
||||
clog << ">>> RigidBody constructed..."<< endlog;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
RigidBody::~RigidBody()
|
||||
{
|
||||
dSpaceDestroy(_Space);
|
||||
dBodyDestroy(_Body);
|
||||
|
||||
std::vector<CollisionMesh>::iterator iter;
|
||||
for (iter = _CollisionMeshes.begin(); iter != _CollisionMeshes.end(); iter++)
|
||||
{
|
||||
dGeomTriMeshDataDestroy((*iter).trimeshdata);
|
||||
}
|
||||
|
||||
clog << ">>> RigidBody destructed..."<< endlog;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const Vector3 &RigidBody::getPosition() const
|
||||
{
|
||||
return _Position;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::setPosition(const Vector3 &v)
|
||||
{
|
||||
dBodySetPosition(_Body, v.x, v.y, v.z);
|
||||
_Position = v;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const Vector3 &RigidBody::getLinearVelocity() const
|
||||
{
|
||||
return _LinearVelocity;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::setLinearVelocity(const Vector3 &v)
|
||||
{
|
||||
dBodySetLinearVel(_Body, v.x, v.y, v.z);
|
||||
_LinearVelocity = v;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const Quaternion &RigidBody::getOrientation() const
|
||||
{
|
||||
return _Orientation;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::setOrientation(const Quaternion &q)
|
||||
{
|
||||
|
||||
dBodySetQuaternion(_Body, ( const dQuaternion & ) q );
|
||||
|
||||
_Orientation = q;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const Vector3 &RigidBody::getAngularVelocity() const
|
||||
{
|
||||
return _AngularVelocity;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::applyGlobalForce(const Vector3 &force, const Vector3 &point)
|
||||
{
|
||||
dBodyAddForceAtPos(_Body, force.x, force.y, force.z, point.x, point.y,
|
||||
point.z);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::applyGlobalForce(const Vector3 &force)
|
||||
{
|
||||
dBodyAddForce(_Body, force.x, force.y, force.z);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::applyLocalForce(const Vector3 &force, const Vector3 &point)
|
||||
{
|
||||
if (point.isZero() )
|
||||
{
|
||||
dBodyAddRelForce(_Body, force.x, force.y, force.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
dBodyAddRelForceAtRelPos(_Body, force.x, force.y, force.z, point.x,
|
||||
point.y, point.z);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::applyLocalForce(const Vector3 &force)
|
||||
{
|
||||
dBodyAddRelForce(_Body, force.x, force.y, force.z);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Scalar RigidBody::getMass() const
|
||||
{
|
||||
dMass m;
|
||||
dBodyGetMass(_Body, &m);
|
||||
return m.mass;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::saveState()
|
||||
{
|
||||
// save position
|
||||
|
||||
const Scalar *p = dBodyGetPosition(_Body);
|
||||
_Position.x = p[0];
|
||||
_Position.y = p[1];
|
||||
_Position.z = p[2];
|
||||
|
||||
// save linear velocity
|
||||
const Scalar *v = dBodyGetLinearVel(_Body);
|
||||
_LinearVelocity.x = v[0];
|
||||
_LinearVelocity.y = v[1];
|
||||
_LinearVelocity.z = v[2];
|
||||
|
||||
// save orientation
|
||||
const Scalar *q = dBodyGetQuaternion(_Body);
|
||||
_Orientation.w = q[0];
|
||||
_Orientation.x = q[1];
|
||||
_Orientation.y = q[2];
|
||||
_Orientation.z = q[3];
|
||||
|
||||
// save angular velocity
|
||||
const Scalar *a = dBodyGetAngularVel(_Body);
|
||||
_AngularVelocity.x = a[0];
|
||||
_AngularVelocity.y = a[1];
|
||||
_AngularVelocity.z = a[2];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned int RigidBody::addCollisionMesh(const std::string &meshname,
|
||||
Scalar density)
|
||||
{
|
||||
if (_Simulation.valid() == false)
|
||||
return 0;
|
||||
|
||||
const RigidBodySimulation::Trimesh *trimesh =
|
||||
_Simulation->getTrimesh(meshname);
|
||||
|
||||
if (trimesh)
|
||||
{
|
||||
CollisionMesh collisionmesh;
|
||||
|
||||
collisionmesh.trimeshdata = dGeomTriMeshDataCreate();
|
||||
dGeomTriMeshDataBuildSingle(collisionmesh.trimeshdata,
|
||||
trimesh->vertices.const_data(), 3 * sizeof(float),
|
||||
trimesh->vertices.count() / 3, trimesh->indices.const_data(),
|
||||
trimesh->indices.count(), 3 * sizeof(int));
|
||||
|
||||
collisionmesh.geom = dCreateTriMesh(_Space, collisionmesh.trimeshdata,
|
||||
0, 0, 0);
|
||||
dGeomSetBody(collisionmesh.geom, _Body);
|
||||
|
||||
dMass mass;
|
||||
dMassSetTrimesh( &mass, density, collisionmesh.geom);
|
||||
//dMassSetBox( &mass, density, 5.0, 5.0, 5.0 );
|
||||
dBodySetMass(_Body, &mass);
|
||||
|
||||
_CollisionMeshes.push_back(collisionmesh);
|
||||
return _CollisionMeshes.size();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::setCollisionMeshPosition(unsigned int geom,
|
||||
const Vector3 &position)
|
||||
{
|
||||
if ( (geom > 0) && (geom <= _CollisionMeshes.size() ))
|
||||
{
|
||||
dGeomSetOffsetPosition(_CollisionMeshes[geom-1].geom, position.x,
|
||||
position.y, position.z);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::setCollisionMeshRotation(unsigned int geom,
|
||||
const Quaternion &rotation)
|
||||
{
|
||||
if ( (geom > 0) && (geom <= _CollisionMeshes.size() ))
|
||||
{
|
||||
dGeomSetOffsetQuaternion(_CollisionMeshes[geom-1].geom,
|
||||
( dReal * ) &rotation );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::getCollisionMeshPosition(unsigned int geom, Vector3 &position)
|
||||
{
|
||||
if ( (geom > 0) && (geom <= _CollisionMeshes.size() ))
|
||||
{
|
||||
const Scalar*p = dGeomGetOffsetPosition(_CollisionMeshes[geom-1].geom);
|
||||
position.x = p[0];
|
||||
position.y = p[1];
|
||||
position.z = p[2];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::getCollisionMeshRotation(unsigned int geom,
|
||||
Quaternion &rotation)
|
||||
{
|
||||
if ( (geom > 0) && (geom <= _CollisionMeshes.size() ))
|
||||
{
|
||||
dGeomGetOffsetQuaternion(_CollisionMeshes[geom-1].geom,
|
||||
( dReal * ) &rotation );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::enableCollisionMesh(unsigned int geom)
|
||||
{
|
||||
if ( (geom > 0) && (geom <= _CollisionMeshes.size() ))
|
||||
{
|
||||
dGeomEnable(_CollisionMeshes[geom-1].geom);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::disableCollisionMesh(unsigned int geom)
|
||||
{
|
||||
if ( (geom > 0) && (geom <= _CollisionMeshes.size() ))
|
||||
{
|
||||
dGeomDisable(_CollisionMeshes[geom-1].geom);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned int RigidBody::getCollisionMeshId(dGeomID geom)
|
||||
{
|
||||
for (unsigned int i = 0; i < _CollisionMeshes.size(); i++)
|
||||
{
|
||||
if (_CollisionMeshes[i].geom == geom)
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
HSQOBJECT RigidBody::getCollisionHandler()
|
||||
{
|
||||
return _CollisionHandler;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBody::setCollisionHandler(HSQOBJECT handler)
|
||||
{
|
||||
_CollisionHandler = handler;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
RigidBodySimulation::RigidBodySimulation(ScriptSystem *scriptsystem) :
|
||||
_world( 0), _space( 0), _contactgroup( 0), _delta( 0.0), _steps( 0),
|
||||
_ScriptSystem(scriptsystem)
|
||||
{
|
||||
dInitODE();
|
||||
|
||||
gRigidBodySimulation = this;
|
||||
//XmlConfig config("config.xml");
|
||||
|
||||
clog << ">>> initialize RigidBodySimulation..."<< endline;
|
||||
|
||||
Scalar erp = 1.0, cfm = 0.0;
|
||||
_stepSize = 0.02;
|
||||
_maxContacts = 5;
|
||||
/*
|
||||
config.getDouble("RigidBodySimulation", "ERP", erp, 1.0);
|
||||
config.getDouble("RigidBodySimulation", "CFM", cfm, 0.0);
|
||||
config.getDouble("RigidBodySimulation", "StepSize", _stepSize, 0.02);
|
||||
config.getInt("RigidBodySimulation", "MaxContacts", _maxContacts, 5);
|
||||
*/
|
||||
// sanity check
|
||||
|
||||
if (erp > 1.0)
|
||||
erp = 1.0;
|
||||
else if (erp < 0.0001)
|
||||
erp = 0.0001;
|
||||
|
||||
clog << " ERP: "<< erp << endline;
|
||||
|
||||
// sanity check
|
||||
if (cfm > 1.0)
|
||||
cfm = 1.0;
|
||||
else if (cfm < 0.0)
|
||||
cfm = 0.0;
|
||||
|
||||
clog << " CFM: "<< cfm << endline;
|
||||
|
||||
// sanity check
|
||||
if (_stepSize < 0.0001)
|
||||
_stepSize = 0.0001;
|
||||
else if (_stepSize > 1.0)
|
||||
_stepSize = 1.0;
|
||||
|
||||
clog << " step size: "<< _stepSize << endline;
|
||||
|
||||
// sanity check
|
||||
if (_maxContacts < 1)
|
||||
_maxContacts = 1;
|
||||
else if (_maxContacts > 500)
|
||||
_maxContacts = 500;
|
||||
|
||||
clog << " max counts: "<< _maxContacts << endline;
|
||||
|
||||
_world = dWorldCreate();
|
||||
|
||||
dWorldSetERP(_world, erp);
|
||||
|
||||
dWorldSetCFM(_world, cfm);
|
||||
|
||||
_space = dHashSpaceCreate( 0);
|
||||
|
||||
dHashSpaceSetLevels(_space, -10, 10);
|
||||
|
||||
_contactgroup = dJointGroupCreate( 0);
|
||||
/*
|
||||
// Bullet
|
||||
btVector3 worldAabbMin(-100000,-100000,-100000);
|
||||
btVector3 worldAabbMax(100000,100000,100000);
|
||||
btOverlappingPairCache* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,32766);
|
||||
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
|
||||
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
|
||||
_World = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver);
|
||||
*/
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
RigidBodySimulation::~RigidBodySimulation()
|
||||
{
|
||||
|
||||
if (_contactgroup)
|
||||
dJointGroupDestroy(_contactgroup);
|
||||
|
||||
if (_space)
|
||||
dSpaceDestroy(_space);
|
||||
|
||||
if (_world)
|
||||
dWorldDestroy(_world);
|
||||
|
||||
std::map<std::string, Trimesh *>::iterator iter;
|
||||
for (iter = _Trimeshes.begin(); iter != _Trimeshes.end(); iter++)
|
||||
{
|
||||
Trimesh *trimesh = iter->second;
|
||||
if (trimesh)
|
||||
delete trimesh;
|
||||
}
|
||||
|
||||
_Trimeshes.clear();
|
||||
|
||||
dCloseODE();
|
||||
|
||||
gRigidBodySimulation = 0;
|
||||
|
||||
clog << ">>> RigidBodySimulation destructed ..."<< endline;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
RigidBody *RigidBodySimulation::createRigidBody()
|
||||
{
|
||||
RigidBody *rigidBody = new RigidBody ( this, _world, _space );
|
||||
|
||||
_bodies.push_back(rigidBody);
|
||||
|
||||
return rigidBody;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBodySimulation::deleteRigidBody(RigidBody *rigidBody)
|
||||
{
|
||||
#ifdef DEBUG_PHYSICS
|
||||
clog << ">>> delete rigid body" << endline;
|
||||
#endif
|
||||
_bodies.remove(rigidBody);
|
||||
delete rigidBody;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBodySimulation::removeAll()
|
||||
{
|
||||
std::list<RigidBody *>::iterator i;
|
||||
|
||||
for (i = _bodies.begin(); i != _bodies.end(); i++)
|
||||
delete *i;
|
||||
|
||||
_bodies.clear();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBodySimulation::saveStates()
|
||||
{
|
||||
std::list<RigidBody *>::iterator i;
|
||||
|
||||
for (i = _bodies.begin(); i != _bodies.end(); i++)
|
||||
( *i )->saveState();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBodySimulation::nearCallback(void *data, dGeomID o1, dGeomID o2)
|
||||
{
|
||||
if (gRigidBodySimulation == 0)
|
||||
return;
|
||||
|
||||
if (dGeomIsSpace(o1) && dGeomIsSpace(o2) )
|
||||
{
|
||||
|
||||
// colliding a space with something
|
||||
dSpaceCollide2(o1, o2, data, &nearCallback);
|
||||
/*
|
||||
// collide all geoms internal to the space(s)
|
||||
if( dGeomIsSpace(o1) )
|
||||
dSpaceCollide( (dxSpace *)o1, data, &nearCallback );
|
||||
|
||||
if( dGeomIsSpace(o2) )
|
||||
dSpaceCollide( (dxSpace *)o2, data,&nearCallback );
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
static Buffer<dContact> contacts;
|
||||
|
||||
if (contacts.count() == 0)
|
||||
contacts.create(gRigidBodySimulation->getMaxContacts());
|
||||
|
||||
dBodyID b1, b2;
|
||||
b1 = dGeomGetBody(o1);
|
||||
b2 = dGeomGetBody(o2);
|
||||
|
||||
// exit without doing anything if the two bodies are connected by a joint
|
||||
if (b1 && b2 && dAreConnected(b1, b2) )
|
||||
return;
|
||||
|
||||
for (unsigned int i = 0; i < contacts.count(); i++)
|
||||
{
|
||||
contacts[i].surface.mode = 0; //dContactBounce;
|
||||
contacts[i].surface.mu = 1.0;
|
||||
contacts[i].surface.mu2 = 0;
|
||||
contacts[i].surface.bounce = 0.1;
|
||||
contacts[i].surface.bounce_vel = 0.1;
|
||||
contacts[i].surface.soft_cfm = 0.01;
|
||||
}
|
||||
|
||||
unsigned int collisions = dCollide(o1, o2, contacts.count(),
|
||||
&contacts[0].geom, sizeof(dContact));
|
||||
|
||||
//clog << "collide" << endline;
|
||||
|
||||
unsigned int actual_collisions = 0;
|
||||
|
||||
for (unsigned int i = 0; i < collisions; i++)
|
||||
{
|
||||
clog << "depth: "<< contacts[i].geom.depth<< endline;
|
||||
dJointID joint = dJointCreateContact(gRigidBodySimulation->_world,
|
||||
gRigidBodySimulation->_contactgroup, &contacts[i]);
|
||||
dJointAttach(joint, b1, b2);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PHYSICS
|
||||
if ( collisions == contacts.count() )
|
||||
clog << "!!! Max collisions reached!" << endline;
|
||||
|
||||
#endif
|
||||
|
||||
if (collisions > 0)
|
||||
{
|
||||
//clog << "rbsim handle collision" << endline;
|
||||
//ScriptManager::getSingleton()->handleCollision ( o1, o2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int RigidBodySimulation::getSteps()
|
||||
{
|
||||
return _steps;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Scalar RigidBodySimulation::getStepSize()
|
||||
{
|
||||
return _stepSize;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int RigidBodySimulation::getMaxContacts()
|
||||
{
|
||||
return _maxContacts;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RigidBodySimulation::updateSteps(Scalar delta)
|
||||
{
|
||||
_delta += delta;
|
||||
|
||||
if (_delta < 0.0)
|
||||
return;
|
||||
|
||||
_steps = ( int ) floor(_delta / _stepSize);
|
||||
|
||||
if (_steps > 10)
|
||||
_steps = 10;
|
||||
|
||||
_delta -= _steps * _stepSize;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool RigidBodySimulation::step()
|
||||
{
|
||||
if (_steps > 0)
|
||||
{
|
||||
_ScriptSystem->callFunction("OnStep", _stepSize);
|
||||
dSpaceCollide(_space, 0, &nearCallback);
|
||||
dWorldQuickStep(_world, _stepSize);
|
||||
StepSignal(_stepSize);
|
||||
dJointGroupEmpty(_contactgroup);
|
||||
_steps--;
|
||||
}
|
||||
|
||||
if (_steps > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const RigidBodySimulation::Trimesh *RigidBodySimulation::getTrimesh(
|
||||
const std::string &name)
|
||||
{
|
||||
Trimesh *trimesh = 0;
|
||||
|
||||
std::map<std::string, Trimesh *>::const_iterator result;
|
||||
result = _Trimeshes.find(name);
|
||||
|
||||
if (result != _Trimeshes.end() )
|
||||
{
|
||||
trimesh = result->second;
|
||||
}
|
||||
/*
|
||||
if ( trimesh == 0 )
|
||||
{
|
||||
MeshLoader loader;
|
||||
|
||||
clog << ">>> loading collision trimesh: " << name << endline;
|
||||
loader.load ( name + ".3ds" );
|
||||
|
||||
if ( loader.objects().count() > 0 )
|
||||
{
|
||||
trimesh = new Trimesh();
|
||||
|
||||
MeshLoader::Object &object = loader.objects().item ( 0 );
|
||||
|
||||
clog << " " << object.vertices.count() << " Vertices" << endline;
|
||||
trimesh->vertices.create ( object.vertices.count() * 3 );
|
||||
|
||||
clog << " " << object.faces.count() * 3 << " Indices" << endline;
|
||||
trimesh->indices.create ( object.faces.count() * 3 );
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for ( i = 0; i < object.vertices.count(); i++ )
|
||||
{
|
||||
trimesh->vertices[i*3] = -object.vertices[i].x;
|
||||
trimesh->vertices[i*3+1] = object.vertices[i].y;
|
||||
trimesh->vertices[i*3+2] = object.vertices[i].z;
|
||||
}
|
||||
|
||||
for ( i = 0; i < object.faces.count(); i++ )
|
||||
{
|
||||
trimesh->indices[i*3] = object.faces[i].a;
|
||||
trimesh->indices[i*3+2] = object.faces[i].b;
|
||||
trimesh->indices[i*3+1] = object.faces[i].c;
|
||||
}
|
||||
|
||||
_Trimeshes[name] = trimesh;
|
||||
}
|
||||
}
|
||||
*/
|
||||
return trimesh;
|
||||
}
|
||||
|
||||
} // namespace BlueCore
|
180
engine/RigidBodySimulation.h
Normal file
180
engine/RigidBodySimulation.h
Normal file
@ -0,0 +1,180 @@
|
||||
#ifndef BLUECORE_RIGID_BODY_SIMULATION_H
|
||||
#define BLUECORE_RIGID_BODY_SIMULATION_H
|
||||
|
||||
// system includes
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "ode/ode.h"
|
||||
#include "squirrel.h"
|
||||
#include "trimeshloader.h"
|
||||
|
||||
// project includes
|
||||
#include "Utilities/Referenced.h"
|
||||
#include "Utilities/Buffer.h"
|
||||
#include "Utilities/sigslot.h"
|
||||
|
||||
#include "Math/Vector.h"
|
||||
#include "Math/Matrix.h"
|
||||
#include "Math/Quaternion.h"
|
||||
|
||||
#include "ScriptSystem.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
class RigidBodySimulation;
|
||||
|
||||
class RigidBody
|
||||
{
|
||||
Vector3 _Position;
|
||||
Quaternion _Orientation;
|
||||
Vector3 _LinearVelocity;
|
||||
Vector3 _AngularVelocity;
|
||||
|
||||
dBodyID _Body;
|
||||
dSpaceID _Space;
|
||||
|
||||
struct CollisionMesh
|
||||
{
|
||||
dTriMeshDataID trimeshdata;
|
||||
dGeomID geom;
|
||||
};
|
||||
|
||||
std::vector<CollisionMesh> _CollisionMeshes;
|
||||
HSQOBJECT _CollisionHandler;
|
||||
weak_ptr<RigidBodySimulation> _Simulation;
|
||||
|
||||
public:
|
||||
|
||||
RigidBody(RigidBodySimulation* simulation, dWorldID world, dSpaceID space);
|
||||
~RigidBody();
|
||||
|
||||
const Vector3 &getPosition() const;
|
||||
void setPosition(const Vector3 &v);
|
||||
|
||||
const Vector3 &getLinearVelocity() const;
|
||||
void setLinearVelocity(const Vector3 &v);
|
||||
|
||||
const Quaternion &getOrientation() const;
|
||||
void setOrientation(const Quaternion &q);
|
||||
|
||||
const Vector3 &getAngularVelocity() const;
|
||||
|
||||
void applyGlobalForce(const Vector3 &force, const Vector3 &point);
|
||||
void applyGlobalForce(const Vector3 &force);
|
||||
|
||||
void applyLocalForce(const Vector3 &force, const Vector3 &point);
|
||||
void applyLocalForce(const Vector3 &force);
|
||||
|
||||
void applyGlobalMomentum(const Vector3 &momentum, const Vector3 &point);
|
||||
void applyLocalMomentum(const Vector3 &momentum, const Vector3 &point);
|
||||
|
||||
Vector3 getLocalLinearMomentum() const;
|
||||
Vector3 getGlobalLinearMomentum() const;
|
||||
|
||||
Vector3 getLocalAngularMomentum() const;
|
||||
Vector3 getGlobalAngularMomentum() const;
|
||||
|
||||
Vector3 getLocalVelocity() const;
|
||||
Vector3 getGlobalVelocity() const;
|
||||
|
||||
Scalar getMass() const;
|
||||
|
||||
sigslot::signal1<RigidBody *> CollisionSignal;
|
||||
|
||||
void saveState();
|
||||
|
||||
unsigned int addCollisionMesh(const std::string &meshname, Scalar density);
|
||||
|
||||
void setCollisionMeshPosition(unsigned int geom, const Vector3 &position);
|
||||
|
||||
void
|
||||
setCollisionMeshRotation(unsigned int geom,
|
||||
const Quaternion &rotation);
|
||||
|
||||
void getCollisionMeshPosition(unsigned int geom, Vector3 &position);
|
||||
|
||||
void getCollisionMeshRotation(unsigned int geom, Quaternion &rotation);
|
||||
|
||||
void enableCollisionMesh(unsigned int geom);
|
||||
|
||||
void disableCollisionMesh(unsigned int geom);
|
||||
|
||||
unsigned int getCollisionMeshId(dGeomID geom);
|
||||
|
||||
HSQOBJECT getCollisionHandler();
|
||||
|
||||
void setCollisionHandler(HSQOBJECT handler);
|
||||
};
|
||||
|
||||
class RigidBodySimulation : public Referenced
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Buffer<float> vertices;
|
||||
Buffer<int> indices;
|
||||
} Trimesh;
|
||||
|
||||
private:
|
||||
|
||||
static void nearCallback(void *data, dGeomID o1, dGeomID o2);
|
||||
|
||||
dWorldID _world;
|
||||
|
||||
dSpaceID _space;
|
||||
|
||||
dJointGroupID _contactgroup;
|
||||
|
||||
int _maxContacts;
|
||||
|
||||
Scalar _delta;
|
||||
|
||||
Scalar _stepSize;
|
||||
|
||||
int _steps;
|
||||
|
||||
std::list<RigidBody *> _bodies;
|
||||
|
||||
std::map<std::string, Trimesh *> _Trimeshes;
|
||||
|
||||
ref_ptr<ScriptSystem> _ScriptSystem;
|
||||
|
||||
public:
|
||||
|
||||
RigidBodySimulation(ScriptSystem *scriptsystem);
|
||||
|
||||
~RigidBodySimulation();
|
||||
|
||||
void initializeSingleton();
|
||||
|
||||
void shutdownSingleton();
|
||||
|
||||
RigidBody *createRigidBody();
|
||||
|
||||
void deleteRigidBody(RigidBody *rigid_body);
|
||||
|
||||
void removeAll();
|
||||
|
||||
int getSteps();
|
||||
|
||||
Scalar getStepSize();
|
||||
|
||||
int getMaxContacts();
|
||||
|
||||
void saveStates();
|
||||
|
||||
void updateSteps(Scalar time);
|
||||
|
||||
bool step();
|
||||
|
||||
sigslot::signal1<Scalar> StepSignal;
|
||||
|
||||
const Trimesh *getTrimesh(const std::string &name);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
162
engine/SceneNode.cpp
Normal file
162
engine/SceneNode.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
#include "SceneNode.h"
|
||||
|
||||
namespace BlueCore {
|
||||
|
||||
#define DEBUG_SCENEGRAPH
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
SceneNode::SceneNode() :
|
||||
Named("unnamed SceneNode"), _Parent(0)
|
||||
{
|
||||
#ifdef DEBUG_SCENEGRAPH
|
||||
clog << "SceneNode 'Unnamed SceneNode' created." << endline;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
SceneNode::SceneNode(const std::string &name) :
|
||||
Named(name), _Parent(0)
|
||||
{
|
||||
#ifdef DEBUG_SCENEGRAPH
|
||||
clog << "SceneNode '" << name << "' created." << endline;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
SceneNode::~SceneNode()
|
||||
{
|
||||
detachAll();
|
||||
|
||||
#ifdef DEBUG_SCENEGRAPH
|
||||
clog << "SceneNode '" << getName() << "' deleted." << endline;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void SceneNode::attach(SceneNode *node)
|
||||
{
|
||||
if (node == 0)
|
||||
return;
|
||||
|
||||
_Children.push_back(node );
|
||||
|
||||
node->_Parent = this;
|
||||
|
||||
node->addReference();
|
||||
|
||||
#ifdef DEBUG_SCENEGRAPH
|
||||
clog << "SceneNode '" << node->getName() << "' attached to '" << this->getName() << "'" << endline;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void SceneNode::detach(SceneNode *node)
|
||||
{
|
||||
node->_Parent = 0;
|
||||
node->removeReference();
|
||||
|
||||
_Children.remove(node );
|
||||
|
||||
#ifdef DEBUG_SCENEGRAPH
|
||||
clog << "SceneNode '" << node->getName() << "' detach from '" << this->getName() << "'" << endline;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void SceneNode::detachAll()
|
||||
{
|
||||
SceneNodeList::iterator i;
|
||||
|
||||
for (i = _Children.begin(); i != _Children.end(); i++)
|
||||
{
|
||||
( *i )->_Parent = 0;
|
||||
( *i )->removeReference();
|
||||
}
|
||||
|
||||
_Children.clear();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
SceneNode *SceneNode::getParent() const
|
||||
{
|
||||
return _Parent;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void SceneNode::detachFromParent()
|
||||
{
|
||||
if (_Parent )
|
||||
_Parent->detach( this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const SceneNode::SceneNodeList& SceneNode::getChildren () const
|
||||
{
|
||||
return _Children;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void SceneNode::update(Scalar time)
|
||||
{
|
||||
updateAbsoluteTransformation();
|
||||
|
||||
// if (isActive() )
|
||||
{
|
||||
SceneNodeList::iterator i;
|
||||
|
||||
for (i = _Children.begin(); i != _Children.end(); i++)
|
||||
( *i )->update(time );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void SceneNode::render(RenderDevice *device, Camera *camera)
|
||||
{
|
||||
if (isActive() )
|
||||
{
|
||||
SceneNodeList::iterator i;
|
||||
|
||||
for (i = _Children.begin(); i != _Children.end(); i++)
|
||||
{
|
||||
( *i )->render(device, camera);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const Transformation& SceneNode::getRelativeTransformation()
|
||||
{
|
||||
return _RelativeTransformation;
|
||||
}
|
||||
|
||||
const Transformation& SceneNode::getAbsoluteTransformation()
|
||||
{
|
||||
return _AbsoluteTransformation;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void SceneNode::setRelativeTranslation(const Vector3 &translation)
|
||||
{
|
||||
_RelativeTransformation.translation = translation;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void SceneNode::setRelativeRotation (const Quaternion &rotation)
|
||||
{
|
||||
_RelativeTransformation.rotation = rotation;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void SceneNode::updateAbsoluteTransformation()
|
||||
{
|
||||
/*
|
||||
if (_Parent )
|
||||
_AbsoluteTranslation = _Parent->getAbsoluteTranslation()
|
||||
+_Parent->getAbsoluteRotation().inversed() * _RelativeTranslation;
|
||||
else
|
||||
_AbsoluteTranslation = _RelativeTranslation;
|
||||
*/
|
||||
}
|
||||
|
||||
} // namespace BlueCore
|
61
engine/SceneNode.h
Normal file
61
engine/SceneNode.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef BLUECORE_SCENE_NODE_H
|
||||
#define BLUECORE_SCENE_NODE_H
|
||||
|
||||
#include "Camera.h"
|
||||
#include "RenderDevice.h"
|
||||
|
||||
#include "Utilities/Referenced.h"
|
||||
#include "Utilities/Named.h"
|
||||
#include "Utilities/Log.h"
|
||||
#include "Utilities/Activated.h"
|
||||
#include "Math/Transformation.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
class SceneNode : public Referenced, public Named, public Activated
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
typedef std::list< ref_ptr<SceneNode> > SceneNodeList;
|
||||
|
||||
protected:
|
||||
|
||||
SceneNode *_Parent;
|
||||
SceneNodeList _Children;
|
||||
Transformation _RelativeTransformation;
|
||||
Transformation _AbsoluteTransformation;
|
||||
|
||||
public:
|
||||
|
||||
SceneNode();
|
||||
SceneNode(const std::string &name);
|
||||
virtual ~SceneNode();
|
||||
|
||||
SceneNode *getParent() const;
|
||||
const SceneNodeList &getChildren() const;
|
||||
|
||||
void attach(SceneNode *node);
|
||||
void detach(SceneNode *node);
|
||||
void detachAll();
|
||||
void detachFromParent();
|
||||
|
||||
virtual void update(Scalar time);
|
||||
virtual void render (RenderDevice *device, Camera *camera);
|
||||
|
||||
const Transformation& getRelativeTransformation();
|
||||
const Transformation& getAbsoluteTransformation();
|
||||
|
||||
void setRelativeTranslation (const Vector3 &translation);
|
||||
void setRelativeRotation (const Quaternion &rotation);
|
||||
|
||||
virtual void updateAbsoluteTransformation();
|
||||
};
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif
|
203
engine/ScriptSystem.cpp
Normal file
203
engine/ScriptSystem.cpp
Normal file
@ -0,0 +1,203 @@
|
||||
#include "ScriptSystem.h"
|
||||
|
||||
#include "Utilities/Log.h"
|
||||
|
||||
// library includes
|
||||
#include "physfs.h"
|
||||
|
||||
// system includes
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
//--------------------------------------------------------------------------
|
||||
static ScriptSystem* gScriptSystem = 0;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void _sq_compiler_error_handler(HSQUIRRELVM vm, const SQChar *error,
|
||||
const SQChar *source, SQInteger line, SQInteger column)
|
||||
{
|
||||
clog << "!!! Error compiling script '"<< source << ":"<< line << ": "
|
||||
<< error << endlog;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static SQInteger _sq_runtime_error_handler(HSQUIRRELVM vm)
|
||||
{
|
||||
const SQChar *error = 0;
|
||||
|
||||
if (sq_gettop(vm) >= 1)
|
||||
{
|
||||
if (SQ_SUCCEEDED(sq_getstring(vm, 2, &error) ) )
|
||||
{
|
||||
clog << "!!! Script Error: "<< error << endlog;
|
||||
}
|
||||
else
|
||||
{
|
||||
clog << "!!! Script Error: unknown"<< endlog;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void _sq_print(HSQUIRRELVM vm, const SQChar* s, ...)
|
||||
{
|
||||
va_list vl;
|
||||
va_start ( vl, s );
|
||||
vprintf(s, vl);
|
||||
va_end ( vl );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static SQInteger _sq_require(HSQUIRRELVM v)
|
||||
{
|
||||
const SQChar *scriptname = 0;
|
||||
|
||||
if (SQ_SUCCEEDED(sq_getstring(v, 2, &scriptname) ))
|
||||
{
|
||||
if (gScriptSystem)
|
||||
gScriptSystem->loadScript(scriptname);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
SQInteger _sq_file_reader(SQUserPointer file)
|
||||
{
|
||||
char c;
|
||||
unsigned int count;
|
||||
|
||||
count = PHYSFS_read( (PHYSFS_file *)file, &c, sizeof (c), 1);
|
||||
if (count > 0)
|
||||
return c;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
ScriptSystem::ScriptSystem()
|
||||
{
|
||||
gScriptSystem = this;
|
||||
|
||||
_VM = sq_open( 1024);
|
||||
sq_setcompilererrorhandler(_VM, _sq_compiler_error_handler);
|
||||
sq_newclosure(_VM, _sq_runtime_error_handler, 0);
|
||||
sq_seterrorhandler(_VM);
|
||||
sq_setprintfunc(_VM, _sq_print);
|
||||
|
||||
sq_pushroottable(_VM);
|
||||
sq_pushstring(_VM, "require", -1);
|
||||
sq_newclosure(_VM, _sq_require, 0);
|
||||
sq_setparamscheck(_VM, 2, ".s");
|
||||
sq_newslot(_VM, -3, false);
|
||||
sq_pop(_VM, 1);
|
||||
|
||||
clog << ">>> ScriptSystem constructed ..."<< endlog;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
ScriptSystem::~ScriptSystem()
|
||||
{
|
||||
sq_close(_VM);
|
||||
clog << ">>> ScriptSystem destructed ..."<< endlog;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
HSQUIRRELVM ScriptSystem::getVM()
|
||||
{
|
||||
return _VM;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool ScriptSystem::loadScript(const std::string &name)
|
||||
{
|
||||
for (unsigned int i = 0; i < _LoadedScripts.size(); i++)
|
||||
{
|
||||
if (_LoadedScripts[i] == name)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (executeScript(name) )
|
||||
{
|
||||
_LoadedScripts.push_back(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
clog << "!!! Script '"<< name << "' not found!"<< endlog;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool ScriptSystem::executeScript(const std::string &name)
|
||||
{
|
||||
string filename = name + ".nut";
|
||||
PHYSFS_file *file = PHYSFS_openRead(filename.c_str() );
|
||||
|
||||
if ( !file)
|
||||
{
|
||||
clog << "!!! Script '"<< name << "' not found!"<< endlog;
|
||||
return false;
|
||||
}
|
||||
|
||||
SQInteger ret;
|
||||
|
||||
ret = sq_compile(_VM, _sq_file_reader, file, name.c_str(), 1);
|
||||
PHYSFS_close(file);
|
||||
|
||||
if (SQ_FAILED(ret) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
sq_pushroottable(_VM);
|
||||
|
||||
ret = sq_call(_VM, 1, SQFalse, SQTrue);
|
||||
sq_pop(_VM, 1);
|
||||
|
||||
if (SQ_FAILED(ret) )
|
||||
{
|
||||
clog << "!!! Script execution failed: "<< name << endlog;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void ScriptSystem::callFunction(const std::string &name)
|
||||
{
|
||||
sq_pushroottable(_VM);
|
||||
sq_pushstring(_VM, name.c_str(), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(_VM, -2)) )
|
||||
{
|
||||
sq_pushroottable(_VM);
|
||||
if (sq_call(_VM, 1, SQTrue, SQTrue) )
|
||||
sq_pop(_VM, 1);
|
||||
}
|
||||
sq_pop(_VM, 1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void ScriptSystem::callFunction(const std::string &name, double value)
|
||||
{
|
||||
sq_pushroottable(_VM);
|
||||
sq_pushstring(_VM, name.c_str(), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(_VM, -2)) )
|
||||
{
|
||||
sq_pushroottable(_VM);
|
||||
sq_pushfloat(_VM, value);
|
||||
if (sq_call(_VM, 2, SQTrue, SQTrue) )
|
||||
sq_pop(_VM, 1);
|
||||
}
|
||||
sq_pop(_VM, 1);
|
||||
}
|
||||
}
|
38
engine/ScriptSystem.h
Normal file
38
engine/ScriptSystem.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef BLUECORE_SCRIPT_SYSTEM_H
|
||||
#define BLUECORE_SCRIPT_SYSTEM_H
|
||||
|
||||
// system includes
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// library includes
|
||||
#include "squirrel.h"
|
||||
|
||||
// project includes
|
||||
#include "Utilities/Referenced.h"
|
||||
|
||||
namespace BlueCore{
|
||||
|
||||
class ScriptSystem : public Referenced
|
||||
{
|
||||
HSQUIRRELVM _VM;
|
||||
|
||||
std::vector<std::string> _LoadedScripts;
|
||||
|
||||
public:
|
||||
|
||||
ScriptSystem();
|
||||
~ScriptSystem();
|
||||
|
||||
HSQUIRRELVM getVM();
|
||||
|
||||
bool executeScript(const std::string &filename);
|
||||
bool loadScript(const std::string &filename);
|
||||
|
||||
void callFunction(const std::string &name);
|
||||
void callFunction(const std::string &name, double value);
|
||||
};
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif
|
126
engine/ScriptSystem_Font.cpp
Normal file
126
engine/ScriptSystem_Font.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include "ScriptSystem_Font.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static weak_ptr<FontManager> gFontManager;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _font_releasehook(SQUserPointer p, SQInteger size)
|
||||
{
|
||||
Font *font = (Font *)p;
|
||||
|
||||
if (font)
|
||||
font->removeReference();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _font_constructor(HSQUIRRELVM vm)
|
||||
{
|
||||
SQInteger argc = sq_gettop (vm );
|
||||
|
||||
Font *font = 0;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
if (gFontManager.valid())
|
||||
font = gFontManager->getDefaultFont();
|
||||
}
|
||||
else
|
||||
{
|
||||
const SQChar *name = 0;
|
||||
SQInteger size = 1;
|
||||
SQBool hinting = SQFalse;
|
||||
|
||||
sq_getstring (vm, 2, &name );
|
||||
sq_getinteger (vm, 3, &size );
|
||||
if (argc > 3)
|
||||
sq_getbool(vm, 4, &hinting );
|
||||
|
||||
if (gFontManager.valid())
|
||||
{
|
||||
font = gFontManager->loadFont(name, size, hinting == SQTrue );
|
||||
if (font)
|
||||
font->addReference();
|
||||
}
|
||||
}
|
||||
|
||||
sq_setinstanceup(vm, 1, (void *)font );
|
||||
sq_setreleasehook (vm, 1, _font_releasehook );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _font_print(HSQUIRRELVM vm)
|
||||
{
|
||||
int argc = sq_gettop (vm );
|
||||
|
||||
if (argc < 4)
|
||||
return 0;
|
||||
|
||||
const Font *font = 0;
|
||||
sq_getinstanceup (vm, 1, ( void ** ) &font, 0);
|
||||
|
||||
if (font)
|
||||
{
|
||||
SQFloat x, y;
|
||||
const char *text;
|
||||
SQInteger halign = 0, valign = 0;
|
||||
|
||||
sq_getfloat (vm, 2, &x );
|
||||
sq_getfloat (vm, 3, &y );
|
||||
sq_getstring(vm, 4, &text);
|
||||
|
||||
if (argc > 4)
|
||||
{
|
||||
sq_getinteger(vm, 5, &halign );
|
||||
}
|
||||
|
||||
if (argc > 5)
|
||||
{
|
||||
sq_getinteger(vm, 6, &valign );
|
||||
}
|
||||
|
||||
font->print( (float)x, (float)y, text, halign, valign );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void setupScriptSystem_Font (ScriptSystem* scriptsystem, FontManager* fontmanager)
|
||||
{
|
||||
if (scriptsystem && fontmanager)
|
||||
{
|
||||
HSQUIRRELVM vm = scriptsystem->getVM();
|
||||
|
||||
gFontManager = fontmanager;
|
||||
|
||||
sq_pushroottable (vm );
|
||||
|
||||
// push class
|
||||
sq_pushstring (vm, "Font", -1);
|
||||
|
||||
if (SQ_SUCCEEDED (sq_newclass (vm, SQFalse ) ) )
|
||||
{
|
||||
// register constructor
|
||||
sq_pushstring (vm, "constructor", -1);
|
||||
sq_newclosure (vm, _font_constructor, 0);
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "print", -1);
|
||||
sq_newclosure (vm, _font_print, 0);
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
// create class
|
||||
sq_newslot (vm, -3, false);
|
||||
}
|
||||
|
||||
sq_poptop (vm );
|
||||
}
|
||||
}
|
||||
}
|
14
engine/ScriptSystem_Font.h
Normal file
14
engine/ScriptSystem_Font.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef BLUECORE_SCRIPTING_FONT_H
|
||||
#define BLUECORE_SCRIPTING_FONT_H
|
||||
|
||||
#include "FontManager.h"
|
||||
#include "ScriptSystem.h"
|
||||
|
||||
#include "squirrel.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
void setupScriptSystem_Font(ScriptSystem* scriptsystem, FontManager* fontmanager);
|
||||
}
|
||||
|
||||
#endif
|
126
engine/ScriptSystem_Image.cpp
Normal file
126
engine/ScriptSystem_Image.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include "ScriptSystem_Image.h"
|
||||
|
||||
#include "TextureImage.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static weak_ptr<TextureManager> gTextureManager;
|
||||
static weak_ptr<RenderDevice> gRenderDevice;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _image_releasehook(SQUserPointer p, SQInteger size)
|
||||
{
|
||||
TextureImage *image = (TextureImage *)p;
|
||||
|
||||
if (image)
|
||||
image->removeReference();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _image_constructor(HSQUIRRELVM vm)
|
||||
{
|
||||
SQInteger argc = sq_gettop (vm );
|
||||
|
||||
if (argc < 6)
|
||||
return 0;
|
||||
|
||||
TextureImage *image = 0;
|
||||
|
||||
const SQChar *texturename = 0;
|
||||
SQFloat ax, ay, bx, by;
|
||||
|
||||
sq_getstring(vm, 2, &texturename );
|
||||
sq_getfloat(vm, 3, &ax );
|
||||
sq_getfloat(vm, 4, &ay );
|
||||
sq_getfloat(vm, 5, &bx );
|
||||
sq_getfloat(vm, 6, &by );
|
||||
|
||||
Texture *texture = gTextureManager->loadTexture(texturename, 0, 0);
|
||||
image = new TextureImage( gRenderDevice.get(), texture, ax, ay, bx, by );
|
||||
image->addReference();
|
||||
|
||||
sq_setinstanceup(vm, 1, (void *)image );
|
||||
sq_setreleasehook (vm, 1, _image_releasehook );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _image_draw(HSQUIRRELVM vm)
|
||||
{
|
||||
int argc = sq_gettop (vm );
|
||||
|
||||
if (argc < 3)
|
||||
return 0;
|
||||
|
||||
TextureImage *image = 0;
|
||||
sq_getinstanceup (vm, 1, ( void ** ) &image, 0);
|
||||
|
||||
if (image )
|
||||
{
|
||||
SQFloat x, y, r = 0.0;
|
||||
SQInteger halign = 0, valign = 0;
|
||||
|
||||
sq_getfloat (vm, 2, &x );
|
||||
sq_getfloat (vm, 3, &y );
|
||||
|
||||
if (argc > 3)
|
||||
{
|
||||
sq_getinteger(vm, 4, &halign );
|
||||
}
|
||||
|
||||
if (argc > 4)
|
||||
{
|
||||
sq_getinteger(vm, 5, &valign );
|
||||
}
|
||||
|
||||
if (argc > 5)
|
||||
{
|
||||
sq_getfloat(vm, 6, &r );
|
||||
}
|
||||
|
||||
image->draw(x, y, halign, valign, r );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void setupScriptSystem_Image(ScriptSystem* scriptsystem,
|
||||
TextureManager* texturemanager, RenderDevice* renderdevice)
|
||||
{
|
||||
if (scriptsystem == 0|| texturemanager == 0|| renderdevice == 0)
|
||||
return;
|
||||
|
||||
gTextureManager = texturemanager;
|
||||
gRenderDevice = renderdevice;
|
||||
|
||||
HSQUIRRELVM vm = scriptsystem->getVM();
|
||||
|
||||
sq_pushroottable (vm );
|
||||
|
||||
// push class
|
||||
sq_pushstring (vm, "Image", -1);
|
||||
|
||||
if (SQ_SUCCEEDED (sq_newclass (vm, SQFalse ) ) )
|
||||
{
|
||||
// register constructor
|
||||
sq_pushstring (vm, "constructor", -1);
|
||||
sq_newclosure (vm, _image_constructor, 0);
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "draw", -1);
|
||||
sq_newclosure (vm, _image_draw, 0);
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
// create class
|
||||
sq_newslot (vm, -3, false);
|
||||
}
|
||||
|
||||
sq_poptop (vm );
|
||||
}
|
||||
}
|
13
engine/ScriptSystem_Image.h
Normal file
13
engine/ScriptSystem_Image.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef BLUECORE_SCRIPTING_IMAGE_H
|
||||
#define BLUECORE_SCRIPTING_IMAGE_H
|
||||
|
||||
#include "ScriptSystem.h"
|
||||
#include "TextureManager.h"
|
||||
#include "RenderDevice.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
void setupScriptSystem_Image (ScriptSystem* scriptsystem, TextureManager* texturemanager, RenderDevice* renderdevice);
|
||||
}
|
||||
|
||||
#endif
|
440
engine/ScriptSystem_Math.cpp
Normal file
440
engine/ScriptSystem_Math.cpp
Normal file
@ -0,0 +1,440 @@
|
||||
#include "ScriptSystem_Math.h"
|
||||
|
||||
#include "Utilities/MersenneTwister.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
static MTRand mtrand;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _sin(HSQUIRRELVM v)
|
||||
{
|
||||
SQFloat f;
|
||||
sq_getfloat (v, 2, &f );
|
||||
sq_pushfloat (v, ( SQFloat ) sin (f ) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _cos(HSQUIRRELVM v)
|
||||
{
|
||||
SQFloat f;
|
||||
sq_getfloat (v, 2, &f );
|
||||
sq_pushfloat (v, ( SQFloat ) cos (f ) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _tan(HSQUIRRELVM v)
|
||||
{
|
||||
SQFloat f;
|
||||
sq_getfloat (v, 2, &f );
|
||||
sq_pushfloat (v, ( SQFloat ) tan (f ) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _sqrt(HSQUIRRELVM v)
|
||||
{
|
||||
SQFloat f;
|
||||
sq_getfloat (v, 2, &f );
|
||||
sq_pushfloat (v, ( SQFloat ) sqrt (f ) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _trunc(HSQUIRRELVM v)
|
||||
{
|
||||
SQFloat f;
|
||||
sq_getfloat (v, 2, &f );
|
||||
sq_pushfloat (v, ( SQFloat ) f - fmod(f, 1.0) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _floor(HSQUIRRELVM v)
|
||||
{
|
||||
SQFloat f;
|
||||
sq_getfloat (v, 2, &f );
|
||||
sq_pushfloat (v, ( SQFloat ) floor (f ) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _ceil(HSQUIRRELVM v)
|
||||
{
|
||||
SQFloat f;
|
||||
sq_getfloat (v, 2, &f );
|
||||
sq_pushfloat (v, ( SQFloat ) ceil (f ) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rand(HSQUIRRELVM v)
|
||||
{
|
||||
sq_pushfloat (v, mtrand.rand() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _seed_rand(HSQUIRRELVM v)
|
||||
{
|
||||
SQInteger seed;
|
||||
sq_getinteger(v, 2, &seed );
|
||||
mtrand.seed(seed );
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void _setup_basic_math (HSQUIRRELVM vm)
|
||||
{
|
||||
sq_pushroottable (vm);
|
||||
|
||||
sq_pushstring (vm, "sin", -1);
|
||||
sq_newclosure (vm, _sin, 0);
|
||||
sq_setparamscheck (vm, 2, ".n");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "cos", -1);
|
||||
sq_newclosure (vm, _cos, 0);
|
||||
sq_setparamscheck (vm, 2, ".n");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "tan", -1);
|
||||
sq_newclosure (vm, _tan, 0);
|
||||
sq_setparamscheck (vm, 2, ".n");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "sqrt", -1);
|
||||
sq_newclosure (vm, _sqrt, 0);
|
||||
sq_setparamscheck (vm, 2, ".n");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "trunc", -1);
|
||||
sq_newclosure (vm, _trunc, 0);
|
||||
sq_setparamscheck (vm, 2, ".n");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "floor", -1);
|
||||
sq_newclosure (vm, _floor, 0);
|
||||
sq_setparamscheck (vm, 2, ".n");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "ceil", -1);
|
||||
sq_newclosure (vm, _ceil, 0);
|
||||
sq_setparamscheck (vm, 2, ".n");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "rand", -1);
|
||||
sq_newclosure (vm, _rand, 0);
|
||||
sq_setparamscheck (vm, 1, ".");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "seed_rand", -1);
|
||||
sq_newclosure (vm, _seed_rand, 0);
|
||||
sq_setparamscheck (vm, 2, ".n");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
// pop the root table
|
||||
sq_pop (vm, 1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _vector__add ( HSQUIRRELVM v )
|
||||
{
|
||||
SQFloat ax, ay, az;
|
||||
SQFloat bx = 0.0, by = 0.0, bz = 0.0;
|
||||
|
||||
_getvectorvalues ( v, 1, ax, ay, az );
|
||||
_getvectorvalues ( v, 2, bx, by, bz );
|
||||
_pushvector ( v, ax + bx, ay + by, az + bz );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _vector__sub ( HSQUIRRELVM v )
|
||||
{
|
||||
SQFloat ax, ay, az;
|
||||
SQFloat bx = 0.0, by = 0.0, bz = 0.0;
|
||||
|
||||
_getvectorvalues ( v, 1, ax, ay, az );
|
||||
_getvectorvalues ( v, 2, bx, by, bz );
|
||||
_pushvector ( v, ax - bx, ay - by, az - bz );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _vector__mul ( HSQUIRRELVM v )
|
||||
{
|
||||
SQFloat x, y, z, f;
|
||||
|
||||
_getvectorvalues ( v, 1, x, y, z );
|
||||
sq_getfloat ( v, 2, &f );
|
||||
_pushvector ( v, x*f, y*f, z*f );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _vector__div ( HSQUIRRELVM v )
|
||||
{
|
||||
SQFloat x, y, z, f;
|
||||
|
||||
_getvectorvalues ( v, 1, x, y, z );
|
||||
sq_getfloat ( v, 2, &f );
|
||||
_pushvector ( v, x / f, y / f, y / f );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _vector_length ( HSQUIRRELVM v )
|
||||
{
|
||||
SQFloat x, y, z;
|
||||
|
||||
_getvectorvalues ( v, 1, x, y, z );
|
||||
|
||||
sq_pushfloat ( v, std::sqrt ( x*x + y*y + z*z ) );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _vector_normalize ( HSQUIRRELVM v )
|
||||
{
|
||||
SQFloat x, y, z;
|
||||
|
||||
_getvectorvalues ( v, 1, x, y, z );
|
||||
|
||||
SQFloat l = 1 / std::sqrt ( x * x + y * y + z * z );
|
||||
_setvectorvalues ( v, 1, x*l, y*l, z*l );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _vector_constructor ( HSQUIRRELVM v )
|
||||
{
|
||||
SQFloat x = 0.0;
|
||||
SQFloat y = 0.0;
|
||||
SQFloat z = 0.0;
|
||||
|
||||
SQInteger argc = sq_gettop ( v );
|
||||
|
||||
if ( argc > 1 )
|
||||
sq_getfloat ( v, 2, &x );
|
||||
|
||||
if ( argc > 2 )
|
||||
sq_getfloat ( v, 3, &y );
|
||||
|
||||
if ( argc > 3 )
|
||||
sq_getfloat ( v, 4, &z );
|
||||
|
||||
_setvectorvalues ( v, 1, x, y, z );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void _register_vector_class( HSQUIRRELVM _vm )
|
||||
{
|
||||
sq_pushroottable ( _vm );
|
||||
|
||||
// push class
|
||||
sq_pushstring ( _vm, "Vector", -1 );
|
||||
if ( SQ_SUCCEEDED ( sq_newclass ( _vm, SQFalse ) ) )
|
||||
{
|
||||
// register variables
|
||||
sq_pushstring ( _vm, "x", -1 );
|
||||
sq_pushfloat ( _vm, 0.0 );
|
||||
sq_newslot ( _vm, -3, false );
|
||||
|
||||
sq_pushstring ( _vm, "y", -1 );
|
||||
sq_pushfloat ( _vm, 0.0 );
|
||||
sq_newslot ( _vm, -3, false );
|
||||
|
||||
sq_pushstring ( _vm, "z", -1 );
|
||||
sq_pushfloat ( _vm, 0.0 );
|
||||
sq_newslot ( _vm, -3, false );
|
||||
|
||||
// register constructor
|
||||
sq_pushstring ( _vm, "constructor", -1 );
|
||||
sq_newclosure ( _vm, _vector_constructor, 0 );
|
||||
sq_newslot ( _vm, -3, false );
|
||||
|
||||
// register _add
|
||||
sq_pushstring ( _vm, "_add", -1 );
|
||||
sq_newclosure ( _vm, _vector__add, 0 );
|
||||
sq_newslot ( _vm, -3, false );
|
||||
|
||||
// register _sub
|
||||
sq_pushstring ( _vm, "_sub", -1 );
|
||||
sq_newclosure ( _vm, _vector__sub, 0 );
|
||||
sq_newslot ( _vm, -3, false );
|
||||
|
||||
// register _mul
|
||||
sq_pushstring ( _vm, "_mul", -1 );
|
||||
sq_newclosure ( _vm, _vector__mul, 0 );
|
||||
sq_newslot ( _vm, -3, false );
|
||||
|
||||
// register _div
|
||||
sq_pushstring ( _vm, "_div", -1 );
|
||||
sq_newclosure ( _vm, _vector__div, 0 );
|
||||
sq_newslot ( _vm, -3, false );
|
||||
|
||||
// register length
|
||||
sq_pushstring ( _vm, "length", -1 );
|
||||
sq_newclosure ( _vm, _vector_length, 0 );
|
||||
sq_newslot ( _vm, -3, false );
|
||||
|
||||
// register normalize
|
||||
sq_pushstring ( _vm, "normalize", -1 );
|
||||
sq_newclosure ( _vm, _vector_normalize, 0 );
|
||||
sq_newslot ( _vm, -3, false );
|
||||
|
||||
// create_vector class
|
||||
sq_newslot ( _vm, -3, false );
|
||||
}
|
||||
|
||||
sq_poptop ( _vm );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _quaternion_constructor ( HSQUIRRELVM v )
|
||||
{
|
||||
SQFloat w = 0.0;
|
||||
SQFloat x = 0.0;
|
||||
SQFloat y = 0.0;
|
||||
SQFloat z = 0.0;
|
||||
|
||||
SQInteger argc = sq_gettop ( v );
|
||||
|
||||
if ( argc > 1 )
|
||||
sq_getfloat ( v, 2, &w );
|
||||
|
||||
if ( argc > 2 )
|
||||
sq_getfloat ( v, 3, &x );
|
||||
|
||||
if ( argc > 3 )
|
||||
sq_getfloat ( v, 4, &y );
|
||||
|
||||
if ( argc > 4 )
|
||||
sq_getfloat ( v, 5, &z );
|
||||
|
||||
_setquaternionvalues ( v, 1, w, x, y, z );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _quaternion_apply ( HSQUIRRELVM vm )
|
||||
{
|
||||
SQFloat qw, qx, qy, qz;
|
||||
SQFloat vx, vy, vz;
|
||||
|
||||
_getquaternionvalues ( vm, 1, qw, qx, qy, qz );
|
||||
_getvectorvalues ( vm, 2, vx, vy, vz );
|
||||
|
||||
SQFloat xx = qx*qx, xy = qx*qy, xz = qx*qz, xw = qx*qw,
|
||||
yy = qy*qy, yz = qy*qz, yw = qy*qw,
|
||||
zz = qz*qz, zw = qz*qw;
|
||||
|
||||
SQFloat rx = 2.0 * (vx * (0.5 - yy - zz) + vy * (xy - zw) + vz * (xz + yw));
|
||||
SQFloat ry = 2.0 * (vx * (xy + zw) + vy * (0.5 - xx - zz) + vz * (yz - xw));
|
||||
SQFloat rz = 2.0 * (vx * (xz - yw) + vy * (yz + xw) + vz * (0.5 - xx - yy));
|
||||
|
||||
_pushvector ( vm, rx, ry, rz );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _quaternion_applyinversed ( HSQUIRRELVM vm )
|
||||
{
|
||||
SQFloat qw, qx, qy, qz;
|
||||
SQFloat vx, vy, vz;
|
||||
|
||||
_getquaternionvalues ( vm, 1, qw, qx, qy, qz );
|
||||
_getvectorvalues ( vm, 2, vx, vy, vz );
|
||||
|
||||
SQFloat xx = qx*qx, xy = qx*qy, xz = qx*qz, xw = -qx*qw,
|
||||
yy = qy*qy, yz = qy*qz, yw = -qy*qw,
|
||||
zz = qz*qz, zw = -qz*qw;
|
||||
|
||||
SQFloat rx = 2.0 * (vx * (0.5 - yy - zz) + vy * (xy - zw) + vz * (xz + yw));
|
||||
SQFloat ry = 2.0 * (vx * (xy + zw) + vy * (0.5 - xx - zz) + vz * (yz - xw));
|
||||
SQFloat rz = 2.0 * (vx * (xz - yw) + vy * (yz + xw) + vz * (0.5 - xx - yy));
|
||||
|
||||
_pushvector ( vm, rx, ry, rz );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void _register_quaternion_class (HSQUIRRELVM vm)
|
||||
{
|
||||
sq_pushroottable ( vm );
|
||||
|
||||
// push class
|
||||
sq_pushstring ( vm, "Quaternion", -1 );
|
||||
|
||||
if ( SQ_SUCCEEDED ( sq_newclass ( vm, SQFalse ) ) )
|
||||
{
|
||||
// register variables
|
||||
sq_pushstring ( vm, "w", -1 );
|
||||
sq_pushfloat ( vm, 0.0 );
|
||||
sq_newslot ( vm, -3, false );
|
||||
|
||||
sq_pushstring ( vm, "x", -1 );
|
||||
sq_pushfloat ( vm, 0.0 );
|
||||
sq_newslot ( vm, -3, false );
|
||||
|
||||
sq_pushstring ( vm, "y", -1 );
|
||||
sq_pushfloat ( vm, 0.0 );
|
||||
sq_newslot ( vm, -3, false );
|
||||
|
||||
sq_pushstring ( vm, "z", -1 );
|
||||
sq_pushfloat ( vm, 0.0 );
|
||||
sq_newslot ( vm, -3, false );
|
||||
|
||||
// register constructor
|
||||
sq_pushstring ( vm, "constructor", -1 );
|
||||
sq_newclosure ( vm, _quaternion_constructor, 0 );
|
||||
sq_newslot ( vm, -3, false );
|
||||
|
||||
sq_pushstring ( vm, "apply", -1 );
|
||||
sq_newclosure ( vm, _quaternion_apply, 0 );
|
||||
sq_newslot ( vm, -3, false );
|
||||
|
||||
sq_pushstring ( vm, "applyInversed", -1 );
|
||||
sq_newclosure ( vm, _quaternion_applyinversed, 0 );
|
||||
sq_newslot ( vm, -3, false );
|
||||
|
||||
// create_vector class
|
||||
sq_newslot ( vm, -3, false );
|
||||
}
|
||||
|
||||
sq_poptop ( vm );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void setupScriptSystem_Math (ScriptSystem* scriptsystem)
|
||||
{
|
||||
if (scriptsystem == 0)
|
||||
return;
|
||||
|
||||
HSQUIRRELVM vm = scriptsystem->getVM();
|
||||
if (vm)
|
||||
{
|
||||
_setup_basic_math (vm);
|
||||
_register_vector_class(vm);
|
||||
_register_quaternion_class(vm);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace BlueCore
|
138
engine/ScriptSystem_Math.h
Normal file
138
engine/ScriptSystem_Math.h
Normal file
@ -0,0 +1,138 @@
|
||||
#ifndef BLUECORE_SCRIPTING_MATH_H
|
||||
#define BLUECORE_SCRIPTING_MATH_H
|
||||
|
||||
#include "ScriptSystem.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline void _setvectorvalues(HSQUIRRELVM &v, const SQInteger &idx,
|
||||
const SQFloat &x, const SQFloat &y, const SQFloat &z)
|
||||
{
|
||||
sq_pushstring (v, "x", 1);
|
||||
sq_pushfloat (v, x );
|
||||
sq_rawset (v, idx );
|
||||
|
||||
sq_pushstring (v, "y", 1);
|
||||
sq_pushfloat (v, y );
|
||||
sq_rawset (v, idx );
|
||||
|
||||
sq_pushstring (v, "z", 1);
|
||||
sq_pushfloat (v, z );
|
||||
sq_rawset (v, idx );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline void _getvectorvalues(HSQUIRRELVM &v, const SQInteger &idx, SQFloat &x,
|
||||
SQFloat &y, SQFloat &z)
|
||||
{
|
||||
sq_pushstring (v, "x", 1);
|
||||
sq_rawget (v, idx );
|
||||
sq_getfloat (v, -1, &x );
|
||||
|
||||
sq_pushstring (v, "y", 1);
|
||||
sq_rawget (v, idx );
|
||||
sq_getfloat (v, -1, &y );
|
||||
|
||||
sq_pushstring (v, "z", 1);
|
||||
sq_rawget (v, idx );
|
||||
sq_getfloat (v, -1, &z );
|
||||
|
||||
sq_pop (v, 3);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline void _pushvector(HSQUIRRELVM &v, const SQFloat &x, const SQFloat &y,
|
||||
const SQFloat &z)
|
||||
{
|
||||
// get closure/class
|
||||
// TODO: use SQObject rfom creation
|
||||
sq_pushroottable (v );
|
||||
sq_pushstring (v, "Vector", -1);
|
||||
sq_get (v, -2);
|
||||
sq_remove (v, -2);
|
||||
|
||||
// call constructor
|
||||
sq_pushroottable (v );
|
||||
sq_pushfloat (v, x );
|
||||
sq_pushfloat (v, y );
|
||||
sq_pushfloat (v, z );
|
||||
sq_call (v, 4, SQTrue, SQTrue );
|
||||
|
||||
// remove class, leave instance
|
||||
sq_remove (v, -2);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline void _pushquaternion(HSQUIRRELVM &v, const SQFloat &w, const SQFloat &x,
|
||||
const SQFloat &y, const SQFloat &z)
|
||||
{
|
||||
// get closure/class
|
||||
// TODO: use SQObject rfom creation!!!!!!
|
||||
sq_pushroottable (v );
|
||||
sq_pushstring (v, "Quaternion", -1);
|
||||
sq_get (v, -2);
|
||||
sq_remove (v, -2);
|
||||
|
||||
// call constructor
|
||||
sq_pushroottable (v );
|
||||
sq_pushfloat (v, w );
|
||||
sq_pushfloat (v, x );
|
||||
sq_pushfloat (v, y );
|
||||
sq_pushfloat (v, z );
|
||||
sq_call (v, 5, SQTrue, SQTrue );
|
||||
|
||||
// remove class, leave instance
|
||||
sq_remove (v, -2);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline void _setquaternionvalues(HSQUIRRELVM &v, const SQInteger &idx,
|
||||
const SQFloat &w, const SQFloat &x, const SQFloat &y, const SQFloat &z)
|
||||
{
|
||||
sq_pushstring (v, "w", -1);
|
||||
sq_pushfloat (v, w );
|
||||
sq_rawset (v, idx );
|
||||
|
||||
sq_pushstring (v, "x", -1);
|
||||
sq_pushfloat (v, x );
|
||||
sq_rawset (v, idx );
|
||||
|
||||
sq_pushstring (v, "y", -1);
|
||||
sq_pushfloat (v, y );
|
||||
sq_rawset (v, idx );
|
||||
|
||||
sq_pushstring (v, "z", -1);
|
||||
sq_pushfloat (v, z );
|
||||
sq_rawset (v, idx );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline void _getquaternionvalues(HSQUIRRELVM &v, const SQInteger &idx,
|
||||
SQFloat &w, SQFloat &x, SQFloat &y, SQFloat &z)
|
||||
{
|
||||
sq_pushstring (v, "w", -1);
|
||||
sq_get (v, idx );
|
||||
sq_getfloat (v, -1, &w );
|
||||
|
||||
sq_pushstring (v, "x", -1);
|
||||
sq_get (v, idx );
|
||||
sq_getfloat (v, -1, &x );
|
||||
|
||||
sq_pushstring (v, "y", -1);
|
||||
sq_get (v, idx );
|
||||
sq_getfloat (v, -1, &y );
|
||||
|
||||
sq_pushstring (v, "z", -1);
|
||||
sq_get (v, idx );
|
||||
sq_getfloat (v, -1, &z );
|
||||
|
||||
sq_pop (v, 3);
|
||||
}
|
||||
|
||||
void setupScriptSystem_Math(ScriptSystem* scriptsystem);
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif
|
542
engine/ScriptSystem_RigidBody.cpp
Normal file
542
engine/ScriptSystem_RigidBody.cpp
Normal file
@ -0,0 +1,542 @@
|
||||
#include "RigidBodySimulation.h"
|
||||
|
||||
#include "ScriptSystem_Math.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static weak_ptr<RigidBodySimulation> gRigidBodySimulation;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_getposition(HSQUIRRELVM v)
|
||||
{
|
||||
RigidBody *body = 0;
|
||||
Vector3 position;
|
||||
|
||||
if (sq_gettop (v ) == 1)
|
||||
{
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
}
|
||||
|
||||
if (body )
|
||||
{
|
||||
position = body->getPosition();
|
||||
_pushvector (v, position.x, position.y, position.z);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_getrotation(HSQUIRRELVM v)
|
||||
{
|
||||
RigidBody *body = 0;
|
||||
Quaternion q;
|
||||
|
||||
if (sq_gettop (v ) == 1)
|
||||
{
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
}
|
||||
|
||||
if (body )
|
||||
{
|
||||
q = body->getOrientation();
|
||||
_pushquaternion (v, q.w, q.x, q.y, q.z);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_getangularvelocity(HSQUIRRELVM v)
|
||||
{
|
||||
RigidBody *body = 0;
|
||||
Vector3 velocity;
|
||||
|
||||
if (sq_gettop (v ) == 1)
|
||||
{
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
}
|
||||
|
||||
if (body )
|
||||
{
|
||||
velocity = body->getAngularVelocity();
|
||||
|
||||
_pushvector (v, velocity.x, velocity.y, velocity.z);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_getlinearvelocity(HSQUIRRELVM v)
|
||||
{
|
||||
RigidBody *body = 0;
|
||||
Vector3 velocity;
|
||||
|
||||
if (sq_gettop (v ) == 1)
|
||||
{
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
}
|
||||
|
||||
if (body )
|
||||
{
|
||||
velocity = body->getLinearVelocity();
|
||||
|
||||
_pushvector (v, velocity.x, velocity.y, velocity.z);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_setposition(HSQUIRRELVM v)
|
||||
{
|
||||
RigidBody *body = 0;
|
||||
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
|
||||
if (body )
|
||||
{
|
||||
Vector3 position;
|
||||
int argc = sq_gettop (v );
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
_getvectorvalues (v, 2, position.x, position.y, position.z);
|
||||
}
|
||||
else if (argc == 4)
|
||||
{
|
||||
sq_getfloat (v, 2, &position.x);
|
||||
sq_getfloat (v, 3, &position.y);
|
||||
sq_getfloat (v, 4, &position.z);
|
||||
}
|
||||
|
||||
body->setPosition(position );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_setlinearvelocity(HSQUIRRELVM v)
|
||||
{
|
||||
RigidBody *body = 0;
|
||||
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
|
||||
if (body )
|
||||
{
|
||||
Vector3 velocity;
|
||||
int argc = sq_gettop (v );
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
_getvectorvalues (v, 2, velocity.x, velocity.y, velocity.z);
|
||||
}
|
||||
else if (argc == 4)
|
||||
{
|
||||
sq_getfloat (v, 2, &velocity.x);
|
||||
sq_getfloat (v, 3, &velocity.y);
|
||||
sq_getfloat (v, 4, &velocity.z);
|
||||
}
|
||||
|
||||
body->setLinearVelocity(velocity );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_setrotation(HSQUIRRELVM v)
|
||||
{
|
||||
RigidBody *body = 0;
|
||||
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
|
||||
if (body )
|
||||
{
|
||||
Quaternion q;
|
||||
int argc = sq_gettop (v );
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
_getquaternionvalues (v, 2, q.w, q.x, q.y, q.z);
|
||||
}
|
||||
else if (argc == 5)
|
||||
{
|
||||
sq_getfloat (v, 2, &q.w);
|
||||
sq_getfloat (v, 3, &q.x);
|
||||
sq_getfloat (v, 4, &q.y);
|
||||
sq_getfloat (v, 5, &q.z);
|
||||
}
|
||||
|
||||
body->setOrientation(q );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_applylocalforce(HSQUIRRELVM v)
|
||||
{
|
||||
RigidBody *body = 0;
|
||||
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
|
||||
if (body )
|
||||
{
|
||||
int argc = sq_gettop (v );
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
Vector3 force;
|
||||
_getvectorvalues (v, 2, force.x, force.y, force.z);
|
||||
body->applyLocalForce(force );
|
||||
}
|
||||
else if (argc == 3)
|
||||
{
|
||||
Vector3 force, point;
|
||||
_getvectorvalues (v, 2, force.x, force.y, force.z);
|
||||
_getvectorvalues (v, 3, point.x, point.y, point.z);
|
||||
body->applyLocalForce(force, point );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_applyglobalforce(HSQUIRRELVM v)
|
||||
{
|
||||
RigidBody *body = 0;
|
||||
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
|
||||
if (body )
|
||||
{
|
||||
int argc = sq_gettop (v );
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
Vector3 force;
|
||||
_getvectorvalues (v, 2, force.x, force.y, force.z);
|
||||
body->applyGlobalForce(force );
|
||||
}
|
||||
else if (argc == 3)
|
||||
{
|
||||
Vector3 force, point;
|
||||
_getvectorvalues (v, 2, force.x, force.y, force.z);
|
||||
_getvectorvalues (v, 3, point.x, point.y, point.z);
|
||||
body->applyGlobalForce(force, point );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_addcollisionmesh(HSQUIRRELVM v)
|
||||
{
|
||||
SQInteger argc = sq_gettop (v );
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
sq_pushinteger (v, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
RigidBody *body = 0;
|
||||
|
||||
const SQChar *meshname = 0;
|
||||
|
||||
SQFloat density = 1.0;
|
||||
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
|
||||
sq_getstring (v, 2, &meshname );
|
||||
|
||||
sq_getfloat (v, 3, &density );
|
||||
|
||||
if (body )
|
||||
{
|
||||
sq_pushinteger (v, body->addCollisionMesh(meshname, density ) );
|
||||
}
|
||||
else
|
||||
sq_pushinteger (v, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_setcollisionmeshposition(HSQUIRRELVM v)
|
||||
{
|
||||
int argc = sq_gettop (v );
|
||||
|
||||
// need at least geom + vector
|
||||
|
||||
if (argc < 3)
|
||||
return 0;
|
||||
|
||||
RigidBody *body = 0;
|
||||
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
|
||||
if (body )
|
||||
{
|
||||
SQInteger geom = 0;
|
||||
sq_getinteger (v, 2, &geom );
|
||||
|
||||
Vector3 position;
|
||||
|
||||
if (argc == 3)
|
||||
{
|
||||
_getvectorvalues (v, 3, position.x, position.y, position.z);
|
||||
}
|
||||
else if (argc == 5)
|
||||
{
|
||||
sq_getfloat (v, 3, &position.x);
|
||||
sq_getfloat (v, 4, &position.y);
|
||||
sq_getfloat (v, 5, &position.z);
|
||||
}
|
||||
|
||||
body->setCollisionMeshPosition(geom, position );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_disablecollisionmesh(HSQUIRRELVM v)
|
||||
{
|
||||
int argc = sq_gettop (v );
|
||||
|
||||
// need at least geom
|
||||
|
||||
if (argc < 2)
|
||||
return 0;
|
||||
|
||||
RigidBody *body = 0;
|
||||
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
|
||||
if (body )
|
||||
{
|
||||
SQInteger geom = 0;
|
||||
sq_getinteger (v, 2, &geom );
|
||||
|
||||
body->disableCollisionMesh(geom );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_enablecollisionmesh(HSQUIRRELVM v)
|
||||
{
|
||||
int argc = sq_gettop (v );
|
||||
|
||||
// need at least geom
|
||||
|
||||
if (argc < 2)
|
||||
return 0;
|
||||
|
||||
RigidBody *body = 0;
|
||||
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
|
||||
if (body )
|
||||
{
|
||||
SQInteger geom = 0;
|
||||
sq_getinteger (v, 2, &geom );
|
||||
|
||||
body->enableCollisionMesh(geom );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_setcollisionmeshrotation(HSQUIRRELVM v)
|
||||
{
|
||||
int argc = sq_gettop (v );
|
||||
|
||||
// need at least geom + quaternion
|
||||
|
||||
if (argc < 3)
|
||||
return 0;
|
||||
|
||||
RigidBody *body = 0;
|
||||
|
||||
sq_getinstanceup (v, 1, ( void ** ) &body, 0);
|
||||
|
||||
if (body )
|
||||
{
|
||||
SQInteger geom = 0;
|
||||
sq_getinteger (v, 2, &geom );
|
||||
|
||||
Quaternion rotation;
|
||||
|
||||
if (argc == 3)
|
||||
{
|
||||
_getquaternionvalues (v, 3, rotation.w, rotation.x, rotation.y,
|
||||
rotation.z);
|
||||
}
|
||||
else if (argc == 4)
|
||||
{
|
||||
Vector3 axis;
|
||||
SQFloat angle;
|
||||
_getvectorvalues (v, 3, axis.x, axis.y, axis.z);
|
||||
sq_getfloat (v, 5, &angle );
|
||||
rotation = Quaternion (axis, angle );
|
||||
}
|
||||
else if (argc == 5)
|
||||
{
|
||||
SQFloat h, a, b;
|
||||
sq_getfloat (v, 3, &h );
|
||||
sq_getfloat (v, 4, &a );
|
||||
sq_getfloat (v, 5, &b );
|
||||
rotation = Quaternion (h, a, b );
|
||||
}
|
||||
|
||||
body->setCollisionMeshRotation(geom, rotation );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_releasehook(SQUserPointer p, SQInteger size)
|
||||
{
|
||||
if (gRigidBodySimulation.valid())
|
||||
{
|
||||
RigidBody *self = ( RigidBody* ) p;
|
||||
gRigidBodySimulation->deleteRigidBody(self );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static SQInteger _rigidbody_constructor(HSQUIRRELVM v)
|
||||
{
|
||||
RigidBody *body = gRigidBodySimulation->createRigidBody();
|
||||
|
||||
if (SQ_FAILED (sq_setinstanceup (v, 1, body ) ) )
|
||||
{
|
||||
gRigidBodySimulation->deleteRigidBody(body );
|
||||
return 0;
|
||||
}
|
||||
|
||||
HSQOBJECT obj;
|
||||
|
||||
sq_getstackobj (v, 2, &obj );
|
||||
body->setCollisionHandler(obj );
|
||||
sq_setreleasehook (v, 1, _rigidbody_releasehook );
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void setupScriptSystem_RigidBody(ScriptSystem *scriptsystem,
|
||||
RigidBodySimulation *simulation)
|
||||
{
|
||||
gRigidBodySimulation = simulation;
|
||||
|
||||
HSQUIRRELVM vm = scriptsystem->getVM();
|
||||
sq_pushroottable(vm );
|
||||
|
||||
sq_pushstring (vm, "RigidBody", -1);
|
||||
if (SQ_SUCCEEDED (sq_newclass (vm, SQFalse ) ) )
|
||||
{
|
||||
// register rigidbody functions
|
||||
sq_pushstring (vm, "constructor", -1);
|
||||
sq_newclosure (vm, _rigidbody_constructor, 0);
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "setPosition", -1);
|
||||
sq_newclosure (vm, _rigidbody_setposition, 0);
|
||||
//sq_setparamscheck( vm, 2, "xx" );
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "getPosition", -1);
|
||||
sq_newclosure (vm, _rigidbody_getposition, 0);
|
||||
sq_setparamscheck (vm, 1, "x");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "setRotation", -1);
|
||||
sq_newclosure (vm, _rigidbody_setrotation, 0);
|
||||
//sq_setparamscheck( vm, 2, "xx" );
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "getRotation", -1);
|
||||
sq_newclosure (vm, _rigidbody_getrotation, 0);
|
||||
sq_setparamscheck (vm, 1, "x");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "getLinearVelocity", -1);
|
||||
sq_newclosure (vm, _rigidbody_getlinearvelocity, 0);
|
||||
sq_setparamscheck (vm, 1, "x");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "setLinearVelocity", -1);
|
||||
sq_newclosure (vm, _rigidbody_setlinearvelocity, 0);
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "getAngularVelocity", -1);
|
||||
sq_newclosure (vm, _rigidbody_getangularvelocity, 0);
|
||||
sq_setparamscheck (vm, 1, "x");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "applyLocalForce", -1);
|
||||
sq_newclosure (vm, _rigidbody_applylocalforce, 0);
|
||||
//sq_setparamscheck (vm, 3, "xxx");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "applyGlobalForce", -1);
|
||||
sq_newclosure (vm, _rigidbody_applyglobalforce, 0);
|
||||
sq_setparamscheck (vm, 3, "xxx");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "addCollisionMesh", -1);
|
||||
sq_newclosure (vm, _rigidbody_addcollisionmesh, 0);
|
||||
sq_setparamscheck (vm, 3, "xsn");
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "setCollisionMeshPosition", -1);
|
||||
sq_newclosure (vm, _rigidbody_setcollisionmeshposition, 0);
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "setCollisionMeshRotation", -1);
|
||||
sq_newclosure (vm, _rigidbody_setcollisionmeshrotation, 0);
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "getCollisionMeshPosition", -1);
|
||||
sq_newclosure (vm, _rigidbody_setcollisionmeshposition, 0);
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "getCollisionMeshRotation", -1);
|
||||
sq_newclosure (vm, _rigidbody_setcollisionmeshrotation, 0);
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "disableCollisionMesh", -1);
|
||||
sq_newclosure (vm, _rigidbody_disablecollisionmesh, 0);
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_pushstring (vm, "enableCollisionMesh", -1);
|
||||
sq_newclosure (vm, _rigidbody_enablecollisionmesh, 0);
|
||||
sq_newslot (vm, -3, false);
|
||||
|
||||
sq_newslot (vm, -3, false);
|
||||
}
|
||||
|
||||
sq_poptop (vm );
|
||||
}
|
||||
|
||||
} // namespace BlueCore
|
12
engine/ScriptSystem_RigidBody.h
Normal file
12
engine/ScriptSystem_RigidBody.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef BLUECORE_SCRIPTING_RIGID_BODY_H
|
||||
#define BLUECORE_SCRIPTING_RIGID_BODY_H
|
||||
|
||||
#include "squirrel.h"
|
||||
#include "RigidBodySimulation.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
void setupScriptSystem_RigidBody( ScriptSystem *scriptsystem, RigidBodySimulation *simulation);
|
||||
}
|
||||
|
||||
#endif
|
332
engine/ShaderManager.cpp
Normal file
332
engine/ShaderManager.cpp
Normal file
@ -0,0 +1,332 @@
|
||||
#include "ShaderManager.h"
|
||||
|
||||
#include "Utilities/Log.h"
|
||||
#include "Utilities/CfgParser.h"
|
||||
|
||||
// library includes
|
||||
#include "physfs.h"
|
||||
|
||||
// system includes
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
ShaderManager::ShaderManager(RenderWindow* renderwindow) :
|
||||
_usingShaders(true), _RenderWindow(renderwindow)
|
||||
{
|
||||
glewInit();
|
||||
|
||||
if (GLEW_ARB_fragment_shader == false)
|
||||
_usingShaders = false;
|
||||
|
||||
_RenderWindow->WindowCloseSignal.connect(this,
|
||||
&ShaderManager::WindowCloseSlot);
|
||||
|
||||
clog << ">>> ShaderManager constructed ..."<< endline;
|
||||
if (_usingShaders)
|
||||
clog << " using shaders"<< endline;
|
||||
else
|
||||
clog << " shaders not supported!"<< endlog;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ShaderManager::~ShaderManager()
|
||||
{
|
||||
clog << ">>> ShaderManager destructed ..."<< endlog;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ShaderManager::shutdown()
|
||||
{
|
||||
clog << ">>> ShaderManager shutting down ..."<< endlog;
|
||||
|
||||
ShaderProgramMap::iterator prog_iter;
|
||||
for (prog_iter = shader_programs.begin(); prog_iter!= shader_programs.end(); prog_iter++)
|
||||
{
|
||||
glDeleteObjectARB(prog_iter->second);
|
||||
}
|
||||
shader_programs.clear();
|
||||
|
||||
VertexShaderMap::iterator vert_iter;
|
||||
for (vert_iter = vertex_shader.begin(); vert_iter != vertex_shader.end(); vert_iter++)
|
||||
{
|
||||
glDeleteObjectARB(vert_iter->second);
|
||||
}
|
||||
vertex_shader.clear();
|
||||
|
||||
FragmentShaderMap::iterator frag_iter;
|
||||
for (frag_iter = fragment_shader.begin(); frag_iter!= fragment_shader.end(); frag_iter++)
|
||||
{
|
||||
glDeleteObjectARB(frag_iter->second);
|
||||
}
|
||||
fragment_shader.clear();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ShaderManager::WindowCloseSlot()
|
||||
{
|
||||
shutdown();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool ShaderManager::usingShaders()
|
||||
{
|
||||
return _usingShaders;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void printInfoLog(GLhandleARB obj)
|
||||
{
|
||||
int infologLength = 0;
|
||||
int charsWritten = 0;
|
||||
char *infoLog;
|
||||
|
||||
glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB,
|
||||
&infologLength);
|
||||
|
||||
if (infologLength > 1)
|
||||
{
|
||||
infoLog = new char[infologLength+1];
|
||||
|
||||
glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
|
||||
|
||||
clog << " "<< infoLog << endline;
|
||||
|
||||
delete [] infoLog;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
VertexShader ShaderManager::loadVertexShader(const string &name)
|
||||
{
|
||||
if ( !_usingShaders)
|
||||
return 0;
|
||||
|
||||
// check if this mesh is already loaded
|
||||
VertexShaderMap::const_iterator result;
|
||||
|
||||
result = vertex_shader.find(name);
|
||||
|
||||
if (result != vertex_shader.end() )
|
||||
{
|
||||
return result->second;
|
||||
}
|
||||
|
||||
string filename = name + ".vert";
|
||||
|
||||
PHYSFS_file *file = PHYSFS_openRead(filename.c_str() );
|
||||
|
||||
if ( !file)
|
||||
{
|
||||
clog << "!!! VertexShader '"<< name << "' not found"<< endline;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *buffer = new char[ PHYSFS_fileLength ( file ) ];
|
||||
|
||||
PHYSFS_read(file, buffer, 1, PHYSFS_fileLength(file) );
|
||||
buffer[ PHYSFS_fileLength ( file ) - 1] = 0;
|
||||
|
||||
PHYSFS_close(file);
|
||||
|
||||
VertexShader shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
|
||||
|
||||
glShaderSourceARB(shader, 1, ( const GLcharARB** ) &buffer, NULL);
|
||||
|
||||
delete [] buffer;
|
||||
|
||||
glCompileShaderARB(shader);
|
||||
|
||||
vertex_shader[name] = shader;
|
||||
|
||||
clog << ">>> VertexShader '"<< name << "' loaded"<< endline;
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
FragmentShader ShaderManager::loadFragmentShader(const string &name)
|
||||
{
|
||||
if ( !_usingShaders)
|
||||
return 0;
|
||||
|
||||
// check if this mesh is already loaded
|
||||
FragmentShaderMap::const_iterator result;
|
||||
|
||||
result = fragment_shader.find(name);
|
||||
|
||||
if (result != fragment_shader.end() )
|
||||
{
|
||||
return result->second;
|
||||
}
|
||||
|
||||
string filename = name + ".frag";
|
||||
|
||||
PHYSFS_file *file = PHYSFS_openRead(filename.c_str() );
|
||||
|
||||
if ( !file)
|
||||
{
|
||||
clog << "!!! FragmentShader '"<< name << "' not found"<< endline;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *buffer = new char[ PHYSFS_fileLength ( file ) ];
|
||||
|
||||
PHYSFS_read(file, buffer, 1, PHYSFS_fileLength(file) );
|
||||
buffer[ PHYSFS_fileLength ( file ) - 1] = 0;
|
||||
|
||||
PHYSFS_close(file);
|
||||
|
||||
FragmentShader shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
|
||||
|
||||
glShaderSourceARB(shader, 1, ( const GLcharARB** ) &buffer, NULL);
|
||||
|
||||
delete [] buffer;
|
||||
|
||||
glCompileShaderARB(shader);
|
||||
|
||||
printInfoLog(shader);
|
||||
|
||||
fragment_shader[name] = shader;
|
||||
|
||||
clog << ">>> FragmentShader '"<< name << "' loaded"<< endline;
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ShaderProgram ShaderManager::loadShaderProgram(const std::string &name)
|
||||
{
|
||||
if ( !_usingShaders)
|
||||
return 0;
|
||||
|
||||
if (name.empty() )
|
||||
return 0;
|
||||
|
||||
// check if this mesh is already loaded
|
||||
ShaderProgramMap::const_iterator result;
|
||||
|
||||
result = shader_programs.find(name);
|
||||
|
||||
if (result != shader_programs.end() )
|
||||
{
|
||||
return result->second;
|
||||
}
|
||||
|
||||
string filename = name + ".prog";
|
||||
|
||||
PHYSFS_file *file = PHYSFS_openRead(filename.c_str() );
|
||||
|
||||
if ( !file)
|
||||
{
|
||||
clog << "!!! ShaderProgramm '"<< name << "' not found"<< endline;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int length = PHYSFS_fileLength(file);
|
||||
char *buffer = new char[length];
|
||||
|
||||
PHYSFS_read(file, buffer, 1, length);
|
||||
PHYSFS_close(file);
|
||||
|
||||
CfgParser cfg;
|
||||
cfg.parse(buffer, length);
|
||||
|
||||
delete [] buffer;
|
||||
|
||||
ShaderProgram program = glCreateProgramObjectARB();
|
||||
|
||||
std::vector<std::string> vertex_shaders;
|
||||
if (cfg.getStrings("vertex_shaders", vertex_shaders) )
|
||||
{
|
||||
for (unsigned int i = 0; i < vertex_shaders.size(); i++)
|
||||
{
|
||||
VertexShader shader = loadVertexShader(vertex_shaders[i]);
|
||||
|
||||
if (shader != 0)
|
||||
glAttachObjectARB(program, shader);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> fragment_shaders;
|
||||
if (cfg.getStrings("fragment_shaders", fragment_shaders) )
|
||||
{
|
||||
for (unsigned int i = 0; i < fragment_shaders.size(); i++)
|
||||
{
|
||||
FragmentShader shader = loadFragmentShader(fragment_shaders[i]);
|
||||
|
||||
if (shader != 0)
|
||||
glAttachObjectARB(program, shader);
|
||||
}
|
||||
}
|
||||
|
||||
glLinkProgramARB(program);
|
||||
|
||||
printInfoLog(program);
|
||||
|
||||
shader_programs[name] = program;
|
||||
|
||||
clog << ">>> ShaderProgramm '"<< name << "' loaded"<< endline;
|
||||
|
||||
return program;
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ShaderManager::useShaderProgram(ShaderProgram shader_program)
|
||||
{
|
||||
if ( !_usingShaders)
|
||||
return;
|
||||
|
||||
glUseProgramObjectARB(shader_program);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ShaderManager::useTexture(ShaderProgram shader_program,
|
||||
unsigned int texture, const std::string &name)
|
||||
{
|
||||
if ( !_usingShaders)
|
||||
return;
|
||||
|
||||
GLint location = glGetUniformLocationARB(shader_program, name.c_str() );
|
||||
|
||||
//if( location > 0 )
|
||||
glUniform1iARB(location, texture);
|
||||
}
|
||||
/*
|
||||
//------------------------------------------------------------------------------
|
||||
void ShaderManager::useTangentBuffer (
|
||||
ShaderProgram shader_program,
|
||||
TangentBuffer *tangent_buffer,
|
||||
const std::string &name )
|
||||
{
|
||||
if ( !_usingShaders || !tangent_buffer )
|
||||
return;
|
||||
|
||||
GLuint location = glGetAttribLocationARB ( shader_program, name.c_str() );
|
||||
|
||||
glEnableVertexAttribArrayARB ( location );
|
||||
|
||||
tangent_buffer->bind();
|
||||
|
||||
glVertexAttribPointerARB ( location, 3, GL_FLOAT, 0, 0, 0 );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ShaderManager::disableTangentBuffer (
|
||||
ShaderProgram shader_program,
|
||||
const std::string &name )
|
||||
{
|
||||
if ( !_usingShaders )
|
||||
return;
|
||||
|
||||
GLuint location = glGetAttribLocationARB ( shader_program, name.c_str() );
|
||||
|
||||
glDisableVertexAttribArrayARB ( location );
|
||||
}
|
||||
*/
|
||||
}
|
66
engine/ShaderManager.h
Normal file
66
engine/ShaderManager.h
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef BLUECORE_SHADER_MANAGER_H
|
||||
#define BLUECORE_SHADER_MANAGER_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "Utilities/Referenced.h"
|
||||
|
||||
#include "TextureManager.h"
|
||||
#include "RenderWindow.h"
|
||||
|
||||
namespace BlueCore {
|
||||
|
||||
typedef GLhandleARB ShaderProgram;
|
||||
typedef GLhandleARB VertexShader;
|
||||
typedef GLhandleARB FragmentShader;
|
||||
|
||||
class ShaderManager : public Referenced, public sigslot::has_slots<>
|
||||
{
|
||||
typedef std::map<std::string, VertexShader> VertexShaderMap;
|
||||
typedef std::map<std::string, FragmentShader> FragmentShaderMap;
|
||||
typedef std::map<std::string, ShaderProgram> ShaderProgramMap;
|
||||
|
||||
VertexShaderMap vertex_shader;
|
||||
FragmentShaderMap fragment_shader;
|
||||
ShaderProgramMap shader_programs;
|
||||
|
||||
VertexShader loadVertexShader(const std::string &name);
|
||||
|
||||
FragmentShader loadFragmentShader(const std::string &name);
|
||||
|
||||
bool _usingShaders;
|
||||
|
||||
ref_ptr<RenderWindow> _RenderWindow;
|
||||
|
||||
void shutdown();
|
||||
|
||||
void WindowCloseSlot();
|
||||
|
||||
public:
|
||||
|
||||
ShaderManager (RenderWindow* renderwindow);
|
||||
|
||||
virtual ~ShaderManager();
|
||||
|
||||
bool usingShaders();
|
||||
|
||||
ShaderProgram loadShaderProgram(const std::string &name);
|
||||
|
||||
void useShaderProgram(ShaderProgram shader_program);
|
||||
|
||||
void useTexture(ShaderProgram shader_program, unsigned int texture,
|
||||
const std::string &name);
|
||||
/*
|
||||
void useTangentBuffer(ShaderProgram shader_program,
|
||||
TangentBuffer *tangent_buffer, const std::string &name);
|
||||
|
||||
void disableTangentBuffer(ShaderProgram shader_program,
|
||||
const std::string &name);*/
|
||||
};
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif
|
146
engine/TextureImage.cpp
Normal file
146
engine/TextureImage.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
#include "TextureImage.h"
|
||||
#include "RenderDevice.h"
|
||||
#include "Utilities/Log.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#if defined(max)
|
||||
#define std::max max
|
||||
#else
|
||||
#define max(a,b) ( a > b ? a : b )
|
||||
#endif
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
TextureImage::TextureImage(RenderDevice* device, Texture *texture, float ax,
|
||||
float ay, float bx, float by) :
|
||||
_Texture(texture), _Device(device)
|
||||
{
|
||||
unsigned int texture_width = _Texture->getWidth();
|
||||
unsigned int texture_height = _Texture->getHeight();
|
||||
|
||||
// greater 0, and values < 1 are fractions of texture dimemsions
|
||||
float e_ax= max( ax <= 1.0 ? texture_width * ax : ax, 0.0f );
|
||||
float e_ay= max( ay <= 1.0 ? texture_height * ay : ay, 0.0f );
|
||||
float e_bx= max( bx <= 1.0 ? texture_width * bx : bx, 0.0f );
|
||||
float e_by= max( by <= 1.0 ? texture_height * by : by, 0.0f );
|
||||
|
||||
float width = e_bx - e_ax;
|
||||
float height = e_by - e_ay;
|
||||
|
||||
// fractional values
|
||||
float au= max( ax > 1.0 ? ax / texture_width : ax, 0.0f );
|
||||
float av= max( ay > 1.0 ? ay / texture_height : ay, 0.0f );
|
||||
float bu= max( bx > 1.0 ? bx / texture_width : bx, 0.0f );
|
||||
float bv= max( by > 1.0 ? by / texture_height : by, 0.0f );
|
||||
|
||||
// bottom left
|
||||
_Vertices[0] = 0.0;
|
||||
_Vertices[1] = 0.0;
|
||||
_TexCoords[0] = au;
|
||||
_TexCoords[1] = 1.0-bv;
|
||||
|
||||
// top left
|
||||
_Vertices[2] = 0.0;
|
||||
_Vertices[3] = height-1;
|
||||
_TexCoords[2] = au;
|
||||
_TexCoords[3] = 1.0-av;
|
||||
|
||||
// top right
|
||||
_Vertices[4] = width-1;
|
||||
_Vertices[5] = height-1;
|
||||
_TexCoords[4] = bu;
|
||||
_TexCoords[5] = 1.0-av;
|
||||
|
||||
// bottom right
|
||||
_Vertices[6] = width-1;
|
||||
_Vertices[7] = 0.0;
|
||||
_TexCoords[6] = bu;
|
||||
_TexCoords[7] = 1.0-bv;
|
||||
|
||||
_Width = (unsigned int)width;
|
||||
_Height = (unsigned int)height;
|
||||
|
||||
clog << ">>> TextureImage constructed..."<< endlog;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
TextureImage::~TextureImage()
|
||||
{
|
||||
clog << ">>> TextureImage destructed..."<< endlog;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void TextureImage::draw(float x, float y, int halign, int valign, float r)
|
||||
{
|
||||
if (!_Device.valid())
|
||||
return;
|
||||
|
||||
_Device->begin2D();
|
||||
|
||||
if (x < 0.0)
|
||||
x += _Device->getViewportWidth();
|
||||
else if (x < 1.0)
|
||||
x *= _Device->getViewportWidth();
|
||||
|
||||
if (halign == -1)
|
||||
x -= _Width;
|
||||
else if (halign == 0)
|
||||
x -= _Width / 2;
|
||||
|
||||
if (y < 0.0)
|
||||
y += _Device->getViewportHeight();
|
||||
else if (y < 1.0)
|
||||
y *= _Device->getViewportHeight();
|
||||
|
||||
if (valign == -1)
|
||||
y -= _Height;
|
||||
else if (valign == 0)
|
||||
y -= _Height / 2;
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, _Texture->getId() );
|
||||
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glTranslatef(x, y, 0);
|
||||
if (r != 0.)
|
||||
glRotatef(r, 0.0, 0.0, 1.0);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2f(_TexCoords[2], _TexCoords[3]);
|
||||
glVertex2f(_Vertices[2], _Vertices[3]);
|
||||
|
||||
glTexCoord2f(_TexCoords[0], _TexCoords[1]);
|
||||
glVertex2f(_Vertices[0], _Vertices[1]);
|
||||
|
||||
glTexCoord2f(_TexCoords[6], _TexCoords[7]);
|
||||
glVertex2f(_Vertices[6], _Vertices[7]);
|
||||
|
||||
glTexCoord2f(_TexCoords[4], _TexCoords[5]);
|
||||
glVertex2f(_Vertices[4], _Vertices[5]);
|
||||
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
_Device->end2D();
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned int TextureImage::getWidth()
|
||||
{
|
||||
return _Width;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned int TextureImage::getHeight()
|
||||
{
|
||||
return _Height;
|
||||
}
|
||||
|
||||
} // namespace BlueCore
|
26
engine/TextureImage.h
Normal file
26
engine/TextureImage.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef BLUECORE_TEXTURE_IMAGE_H
|
||||
#define BLUECORE_TEXTURE_IMAGE_H
|
||||
|
||||
#include "TextureManager.h"
|
||||
#include "RenderDevice.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
class TextureImage : public Referenced
|
||||
{
|
||||
ref_ptr<Texture> _Texture;
|
||||
ref_ptr<RenderDevice> _Device;
|
||||
float _Vertices[3 * 4];
|
||||
float _TexCoords[2 * 4];
|
||||
unsigned int _Width, _Height;
|
||||
|
||||
public:
|
||||
TextureImage (RenderDevice* device, Texture *texture, float ax, float ay, float bx, float by );
|
||||
~TextureImage();
|
||||
void draw (float x, float y, int halign = 0, int valign = 0, float r = 0.0 );
|
||||
unsigned int getWidth();
|
||||
unsigned int getHeight();
|
||||
};
|
||||
}
|
||||
|
||||
#endif /*IMAGE_H_*/
|
444
engine/TextureManager.cpp
Normal file
444
engine/TextureManager.cpp
Normal file
@ -0,0 +1,444 @@
|
||||
#include "TextureManager.h"
|
||||
|
||||
#include "Utilities/Log.h"
|
||||
#include "Utilities/format.h"
|
||||
|
||||
// library includes
|
||||
//#include "png.h"
|
||||
#include "physfs.h"
|
||||
#include "corona.h"
|
||||
#include "GL/glew.h"
|
||||
|
||||
// system includes
|
||||
#include <fstream>
|
||||
#include <limits.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
TextureManager::TextureManager()
|
||||
{
|
||||
_maxAnisotopy = 128.0;
|
||||
_maxTextureSize = 1024 * 16;
|
||||
_lodDrop = 0;
|
||||
_textureCompression = true;
|
||||
|
||||
glewInit();
|
||||
|
||||
if (GLEW_ARB_texture_compression == false)
|
||||
_textureCompression = false;
|
||||
|
||||
clog << ">>> TextureManager constructed ..."<< endline;
|
||||
if (_textureCompression)
|
||||
clog << " using texture compression"<< endline;
|
||||
else
|
||||
clog << " texture compression not supported!"<< endline;
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
TextureManager::~TextureManager()
|
||||
{
|
||||
clog << ">>> TextureManager destructed ..."<< endline;
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
glDeleteTextures( 1, &_Id);
|
||||
clog << ">>> Texture destructed ..."<< endline;
|
||||
}
|
||||
/*
|
||||
//------------------------------------------------------------------------------
|
||||
void TextureManager::initializeSingleton()
|
||||
{
|
||||
|
||||
XmlConfig config("config.xml");
|
||||
|
||||
_lodDrop = 0;
|
||||
|
||||
config.getBool("TextureManager", "TextureCompression", _textureCompression,
|
||||
true);
|
||||
|
||||
if (GLEW_ARB_texture_compression == false)
|
||||
_textureCompression = false;
|
||||
|
||||
if (_textureCompression )
|
||||
clog << " using texture compression"<< endline;
|
||||
else
|
||||
clog << " texture compression not supported!"<< endline;
|
||||
|
||||
config.getUInt("TextureManager", "MaxTextureSize", _maxTextureSize, 8192);
|
||||
|
||||
GLint maxTextureSize;
|
||||
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &maxTextureSize );
|
||||
|
||||
if (_maxTextureSize > (unsigned int)maxTextureSize )
|
||||
_maxTextureSize = maxTextureSize;
|
||||
|
||||
clog << " maximum texture size: "<< _maxTextureSize << endline;
|
||||
|
||||
config.getFloat("TextureManager", "MaxAnisotopy", _maxAnisotopy, 128.0);
|
||||
|
||||
float maxAnisotopy = 0.0;
|
||||
|
||||
if (GLEW_EXT_texture_filter_anisotropic )
|
||||
glGetFloatv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotopy );
|
||||
|
||||
if (_maxAnisotopy > maxAnisotopy )
|
||||
_maxAnisotopy = maxAnisotopy;
|
||||
|
||||
if (_maxAnisotopy > 1.0)
|
||||
clog << " using anisotopic texture filtering, level: "<< _maxAnisotopy
|
||||
<< endlog;
|
||||
else
|
||||
clog << " not using anisotopic texture filtering."<< endlog;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void TextureManager::shutdownSingleton()
|
||||
{
|
||||
clog << ">>> shutdown TextureManager..."<< endline;
|
||||
|
||||
clearTextures();
|
||||
}
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool TextureManager::saveToCache(const std::string &filename, int levels)
|
||||
{
|
||||
unsigned char *data = 0;
|
||||
GLint internalformat, compressed_size = 0, width = 0, height = 0, level = 0;
|
||||
|
||||
PHYSFS_file *file = PHYSFS_openWrite(filename.c_str() );
|
||||
|
||||
if ( !file)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
level = 0;
|
||||
|
||||
while ( !PHYSFS_eof(file) )
|
||||
{
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, level,
|
||||
GL_TEXTURE_INTERNAL_FORMAT, &internalformat);
|
||||
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, level,
|
||||
GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &compressed_size);
|
||||
|
||||
if (compressed_size == 0)
|
||||
break;
|
||||
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
|
||||
|
||||
if (width == 0)
|
||||
break;
|
||||
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_HEIGHT,
|
||||
&height);
|
||||
|
||||
if (height == 0)
|
||||
break;
|
||||
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, level,
|
||||
GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &compressed_size);
|
||||
|
||||
data = new unsigned char[ compressed_size ];
|
||||
|
||||
glGetCompressedTexImageARB(GL_TEXTURE_2D, level, data);
|
||||
|
||||
PHYSFS_write(file, &internalformat, sizeof (internalformat ), 1);
|
||||
PHYSFS_write(file, &level, sizeof (level ), 1);
|
||||
PHYSFS_write(file, &width, sizeof (width ), 1);
|
||||
PHYSFS_write(file, &height, sizeof (height ), 1);
|
||||
PHYSFS_write(file, &compressed_size, sizeof (compressed_size ), 1);
|
||||
PHYSFS_write(file, data, compressed_size, 1);
|
||||
|
||||
delete [] data;
|
||||
|
||||
level += 1;
|
||||
|
||||
if ( (width == 1 ) && (height == 1 ))
|
||||
break;
|
||||
|
||||
if (level >= levels)
|
||||
break;
|
||||
}
|
||||
|
||||
PHYSFS_close(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool TextureManager::loadFromCache(const std::string &filename,
|
||||
unsigned int &max_width, unsigned int &max_height)
|
||||
{
|
||||
unsigned char *data = 0;
|
||||
GLuint internalformat, compressed_size, width, height, level;
|
||||
|
||||
max_width = 0;
|
||||
max_height = 0;
|
||||
|
||||
PHYSFS_file *file = PHYSFS_openRead(filename.c_str() );
|
||||
|
||||
if ( !file)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
while ( !PHYSFS_eof(file) )
|
||||
{
|
||||
PHYSFS_read(file, &internalformat, sizeof (internalformat ), 1);
|
||||
PHYSFS_read(file, &level, sizeof (level ), 1);
|
||||
PHYSFS_read(file, &width, sizeof (width ), 1);
|
||||
PHYSFS_read(file, &height, sizeof (height ), 1);
|
||||
PHYSFS_read(file, &compressed_size, sizeof (compressed_size ), 1);
|
||||
|
||||
if ( !data)
|
||||
data = new unsigned char[ compressed_size ];
|
||||
|
||||
PHYSFS_read(file, data, compressed_size, 1);
|
||||
|
||||
glCompressedTexImage2DARB(GL_TEXTURE_2D, level, internalformat, width,
|
||||
height, 0, compressed_size, data);
|
||||
|
||||
max_width = max(width, max_width);
|
||||
max_height = max(height, max_height);
|
||||
|
||||
if (width == 1 && height == 1)
|
||||
break;
|
||||
}
|
||||
|
||||
delete [] data;
|
||||
|
||||
PHYSFS_close(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Texture *TextureManager::loadTexture(const std::string &filename,
|
||||
int mipmapLevel, int compressionLevel)
|
||||
{
|
||||
if (filename.empty() )
|
||||
return 0;
|
||||
|
||||
std::string cachename = filename;
|
||||
cachename += "_";
|
||||
cachename += format("%d", mipmapLevel);
|
||||
cachename += "_";
|
||||
cachename += format("%d", compressionLevel);
|
||||
cachename += ".cache";
|
||||
|
||||
TextureMap::const_iterator result;
|
||||
result = textures.find(filename);
|
||||
|
||||
if (result != textures.end() )
|
||||
{
|
||||
return result->second;
|
||||
}
|
||||
|
||||
GLint UnpackAlignment;
|
||||
|
||||
// Set unpack alignment to one byte
|
||||
glGetIntegerv(GL_UNPACK_ALIGNMENT, &UnpackAlignment);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
unsigned int id = 0;
|
||||
glGenTextures( 1, &id);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
|
||||
if (mipmapLevel == 0)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR_MIPMAP_NEAREST);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
if (_maxAnisotopy > 0.0)
|
||||
{
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||
( float ) _maxAnisotopy );
|
||||
}
|
||||
|
||||
Texture *t = 0;
|
||||
unsigned int width = 0, height = 0;
|
||||
|
||||
// check for cached texture
|
||||
if (_textureCompression && (compressionLevel > 0))
|
||||
{
|
||||
PHYSFS_sint64 mod_file = PHYSFS_getLastModTime(filename.c_str() );
|
||||
PHYSFS_sint64 mod_config = PHYSFS_getLastModTime("config.xml");
|
||||
|
||||
PHYSFS_sint64 mod_cache = PHYSFS_getLastModTime(cachename.c_str() );
|
||||
|
||||
if ( (mod_cache > mod_file) && (mod_cache > mod_config))
|
||||
{
|
||||
if (loadFromCache(cachename, width, height) )
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, UnpackAlignment);
|
||||
clog << ">>> Texture '" << filename << "' loaded from cache ("
|
||||
<< width << ", " << height << ")." << endline;
|
||||
t = new Texture( id, width, height );
|
||||
textures[filename] = t;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//clog << ">>> Texture '" << filename << "': loading from file..." << endline;
|
||||
corona::Image *image = corona::OpenImage(filename.c_str(),
|
||||
corona::PF_R8G8B8A8);
|
||||
if (image)
|
||||
{
|
||||
int level = 0;
|
||||
unsigned int width_scaled = image->getWidth();
|
||||
unsigned int height_scaled = image->getHeight();
|
||||
|
||||
corona::FlipImage(image, corona::CA_X);
|
||||
// create mipmaps
|
||||
while ( 1)
|
||||
{
|
||||
if ( (width_scaled <= _maxTextureSize ) && (height_scaled
|
||||
<= _maxTextureSize ))
|
||||
{
|
||||
width = max(width_scaled, width);
|
||||
height = max(height_scaled, height);
|
||||
|
||||
if (_textureCompression && (compressionLevel > 0))
|
||||
{
|
||||
glHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_NICEST);
|
||||
|
||||
GLuint compression = GL_COMPRESSED_RGBA_ARB;
|
||||
if (GLEW_EXT_texture_compression_s3tc)
|
||||
{
|
||||
if (compressionLevel == 1)
|
||||
compression = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
else if (compressionLevel == 2)
|
||||
compression = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
else
|
||||
compression = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, level, compression,
|
||||
width_scaled, height_scaled, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, ( void* ) image->getPixels() );
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, width_scaled,
|
||||
height_scaled, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
( void* ) image->getPixels() );
|
||||
}
|
||||
|
||||
level += 1;
|
||||
}
|
||||
|
||||
if ( (width_scaled == 1 ) && (height_scaled == 1 ))
|
||||
break;
|
||||
|
||||
if ( (mipmapLevel >= 0 ) && (level >= mipmapLevel ))
|
||||
break;
|
||||
|
||||
// rescale image
|
||||
int halfwidth = width_scaled > 1 ? width_scaled / 2 : 1;
|
||||
int halfheight = height_scaled > 1 ? height_scaled / 2 : 1;
|
||||
int idx1 = width_scaled * 4;
|
||||
int idx2 = (width_scaled + 1 ) * 4;
|
||||
unsigned char *dst = (unsigned char *)image->getPixels();
|
||||
unsigned char *src = (unsigned char *)image->getPixels();
|
||||
|
||||
for (int y = 0; y < halfheight; y++)
|
||||
{
|
||||
for (int x = 0; x < halfwidth; x++)
|
||||
{
|
||||
for (int k = 0; k < 4; k ++)
|
||||
{
|
||||
*dst ++ = ( GLubyte ) ( ( ( int ) *src + ( int ) src[4]
|
||||
+ ( int ) src[idx1] + ( int ) src[idx2] + 2 )
|
||||
>> 2 );
|
||||
src ++;
|
||||
}
|
||||
|
||||
src += 4;
|
||||
}
|
||||
|
||||
src += 4 * width_scaled;
|
||||
}
|
||||
|
||||
width_scaled = halfheight;
|
||||
height_scaled = halfwidth;
|
||||
}
|
||||
|
||||
delete image;
|
||||
|
||||
if (_textureCompression && (compressionLevel > 0))
|
||||
saveToCache(cachename, level);
|
||||
|
||||
t = new Texture( id, width, height );
|
||||
clog << ">>> Texture '" << filename << "': loaded from file" << endline;
|
||||
}
|
||||
else
|
||||
{
|
||||
glDeleteTextures( 1, &id);
|
||||
t = new Texture( 0, 0, 0 );
|
||||
clog << "!!! Texture '" << filename << "' not found!" << endline;
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, UnpackAlignment);
|
||||
|
||||
textures[filename] = t;
|
||||
|
||||
return t;
|
||||
}
|
||||
/*
|
||||
//------------------------------------------------------------------------------
|
||||
void TextureManager::releaseTexture ( const Texture *texture )
|
||||
{
|
||||
Texture *t = (Texture *)texture;
|
||||
|
||||
if( t->_RefCount > 1 )
|
||||
t->_RefCount--;
|
||||
else if( t->_RefCount == 1 )
|
||||
{
|
||||
glDeleteTextures ( 1, &t->_Id );
|
||||
delete t;
|
||||
|
||||
TextureMap::iterator i;
|
||||
for( i = textures.begin(); i != textures.end(); i++ )
|
||||
{
|
||||
if( (*i).second == t )
|
||||
{
|
||||
textures.erase( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
//------------------------------------------------------------------------------
|
||||
void TextureManager::TextureDestroySlot(Referenced *referenced)
|
||||
{
|
||||
TextureMap::iterator i;
|
||||
|
||||
for (i = textures.begin(); i != textures.end(); i++)
|
||||
{
|
||||
Texture *t = (*i).second;
|
||||
if (t == (Texture*)referenced)
|
||||
{
|
||||
textures.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
92
engine/TextureManager.h
Normal file
92
engine/TextureManager.h
Normal file
@ -0,0 +1,92 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Author: Gero Mueller <gero.mueller@cloo.de>
|
||||
// Copyright: (c) 2006 Gero Mueller
|
||||
// License: MIT License
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BLUECORE_TEXTURE_MANAGER_H
|
||||
#define BLUECORE_TEXTURE_MANAGER_H
|
||||
|
||||
// system includes
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
// project includes
|
||||
#include "Utilities/Referenced.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
// forward declaration
|
||||
class TextureManager;
|
||||
|
||||
class Texture : public Referenced
|
||||
{
|
||||
unsigned int _Id;
|
||||
unsigned int _Width, _Height;
|
||||
|
||||
~Texture();
|
||||
|
||||
public:
|
||||
|
||||
Texture( unsigned int id, unsigned int width, unsigned int height ) :
|
||||
_Id( id ),
|
||||
_Width( width ),
|
||||
_Height( height )
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int getWidth() const
|
||||
{
|
||||
return _Width;
|
||||
}
|
||||
|
||||
unsigned int getHeight() const
|
||||
{
|
||||
return _Height;
|
||||
}
|
||||
|
||||
unsigned int getId() const
|
||||
{
|
||||
return _Id;
|
||||
}
|
||||
};
|
||||
|
||||
class TextureManager : public Referenced
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef std::map<std::string, Texture *> TextureMap;
|
||||
|
||||
TextureMap textures;
|
||||
|
||||
float _maxAnisotopy;
|
||||
unsigned int _maxTextureSize;
|
||||
unsigned int _lodDrop;
|
||||
bool _textureCompression;
|
||||
|
||||
void clearTextures();
|
||||
|
||||
bool saveToCache ( const std::string &name, int levels );
|
||||
|
||||
bool loadFromCache (
|
||||
const std::string &filename,
|
||||
unsigned int &max_width,
|
||||
unsigned int &max_height );
|
||||
|
||||
~TextureManager();
|
||||
|
||||
void TextureDestroySlot(Referenced *referenced);
|
||||
|
||||
public:
|
||||
|
||||
TextureManager();
|
||||
|
||||
Texture *loadTexture (
|
||||
const std::string &filename,
|
||||
int mipmapLevel = -1,
|
||||
int compressionLevel = 1 );
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
87
engine/Utilities/Activated.h
Normal file
87
engine/Utilities/Activated.h
Normal file
@ -0,0 +1,87 @@
|
||||
#ifndef BLUECORE_ACTIVATED_H
|
||||
#define BLUECORE_ACTIVATED_H
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
class Activated
|
||||
{
|
||||
private:
|
||||
|
||||
bool _Active;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* inital state is active
|
||||
*/
|
||||
inline Activated()
|
||||
{
|
||||
_Active = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param set inital state
|
||||
*/
|
||||
inline Activated(bool state) :
|
||||
_Active(state )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual inline ~Activated()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the object.
|
||||
*/
|
||||
inline void activate()
|
||||
{
|
||||
_Active = true;
|
||||
onActivation();
|
||||
}
|
||||
|
||||
virtual void onActivation()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the object.
|
||||
*/
|
||||
inline void deactivate()
|
||||
{
|
||||
_Active = false;
|
||||
onDeactivation();
|
||||
}
|
||||
|
||||
virtual void onDeactivation()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* toggles the object's state
|
||||
*/
|
||||
inline void toggleActive()
|
||||
{
|
||||
if (_Active )
|
||||
deactivate();
|
||||
else
|
||||
activate();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the object's state
|
||||
*/
|
||||
inline bool isActive()
|
||||
{
|
||||
return _Active;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif // BLUECORE_ACTIVATED_H
|
151
engine/Utilities/Buffer.h
Normal file
151
engine/Utilities/Buffer.h
Normal file
@ -0,0 +1,151 @@
|
||||
#ifndef BLUECORE_BUFFER_H
|
||||
#define BLUECORE_BUFFER_H
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
template<class T>
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
|
||||
private:
|
||||
|
||||
type *_buffer;
|
||||
unsigned int _count;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
Buffer() :
|
||||
_buffer( 0 ),
|
||||
_count( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor with initial size
|
||||
*/
|
||||
Buffer( unsigned int count ) :
|
||||
_buffer( 0 ),
|
||||
_count( 0 )
|
||||
{
|
||||
create( count );
|
||||
}
|
||||
|
||||
/**
|
||||
* destructor
|
||||
*/
|
||||
virtual ~Buffer()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* create the buffer
|
||||
*/
|
||||
bool create( unsigned int count )
|
||||
{
|
||||
destroy();
|
||||
|
||||
_buffer = new type[count];
|
||||
|
||||
if( _buffer )
|
||||
{
|
||||
_count = count;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* destroy the buffer
|
||||
*/
|
||||
void destroy()
|
||||
{
|
||||
delete [] _buffer;
|
||||
_buffer = 0;
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
void resize( unsigned int new_count )
|
||||
{
|
||||
type *new_buffer = new type[new_count];
|
||||
|
||||
for( unsigned int i = 0; i<_count; i++ )
|
||||
new_buffer[i] = _buffer[i];
|
||||
|
||||
destroy();
|
||||
|
||||
_buffer = new_buffer;
|
||||
_count = new_count;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the item count
|
||||
*/
|
||||
unsigned int count() const
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the buffer size in bytes
|
||||
*/
|
||||
unsigned int size() const
|
||||
{
|
||||
return _count * sizeof(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a pointer to the data
|
||||
*/
|
||||
type *data()
|
||||
{
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* return a pointer to the(const) data
|
||||
*/
|
||||
const type *const_data() const
|
||||
{
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* array operator
|
||||
*/
|
||||
type &operator[](const unsigned int index)
|
||||
{
|
||||
if( index >= _count )
|
||||
throw std::range_error("Buffer::[] index_out_of_bound!");
|
||||
return _buffer[index];
|
||||
}
|
||||
|
||||
type &item(const unsigned int index)
|
||||
{
|
||||
if( index >= _count )
|
||||
throw std::range_error("Buffer::[] index_out_of_bound!");
|
||||
return _buffer[index];
|
||||
}
|
||||
|
||||
const type &const_item(const unsigned int index) const
|
||||
{
|
||||
if( index >= _count )
|
||||
throw std::range_error("Buffer::[] index_out_of_bound!");
|
||||
return _buffer[index];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
198
engine/Utilities/CfgParser.cpp
Normal file
198
engine/Utilities/CfgParser.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
#include "CfgParser.h"
|
||||
#include "StringUtilities.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace BlueCore {
|
||||
|
||||
void CfgParser::parseFile (const std::string& filename)
|
||||
{
|
||||
ifstream file (filename.c_str(), ios::in);
|
||||
std::string line;
|
||||
|
||||
while (file.good())
|
||||
{
|
||||
getline (file, line);
|
||||
parseLine (line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CfgParser::parseLine (const std::string& line)
|
||||
{
|
||||
std::string::size_type i (line.find_first_of ('='));
|
||||
|
||||
if (i == std::string::npos)
|
||||
return;
|
||||
|
||||
std::string key = trim (string (line, 0, i-1));
|
||||
std::string value = trim (string (line, i+1));
|
||||
|
||||
_Pairs[key] = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CfgParser::parse (const char* buffer, unsigned int length)
|
||||
{
|
||||
const char* ptr = buffer;
|
||||
const char* end = buffer + length;
|
||||
unsigned int l = 0;
|
||||
|
||||
while (ptr < end)
|
||||
{
|
||||
// find end of line
|
||||
while (ptr[l] != '\n')
|
||||
{
|
||||
l++;
|
||||
if (ptr + l >= end)
|
||||
break;
|
||||
}
|
||||
|
||||
parseLine (string(ptr, l));
|
||||
ptr += l+1;
|
||||
l = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
double CfgParser::get (const std::string& key, double defaultValue)
|
||||
{
|
||||
double value;
|
||||
|
||||
if (getDouble (key, value) == false)
|
||||
return defaultValue;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CfgParser::getDouble (const std::string& key, double& value)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator result;
|
||||
result = _Pairs.find (key);
|
||||
|
||||
if (result != _Pairs.end())
|
||||
{
|
||||
value = atof (result->second.c_str());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int CfgParser::get (const std::string& key, int defaultValue)
|
||||
{
|
||||
int value;
|
||||
|
||||
if (getInteger (key, value) == false)
|
||||
return defaultValue;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CfgParser::getInteger (const std::string& key, int& value)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator result;
|
||||
result = _Pairs.find (key);
|
||||
|
||||
if (result != _Pairs.end())
|
||||
{
|
||||
value = atoi (result->second.c_str());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CfgParser::get (const std::string& key, bool defaultValue)
|
||||
{
|
||||
bool value;
|
||||
|
||||
if (getBoolean (key, value) == false)
|
||||
return defaultValue;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CfgParser::getBoolean (const std::string& key, bool& value)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator result;
|
||||
result = _Pairs.find (key);
|
||||
|
||||
if (result != _Pairs.end())
|
||||
{
|
||||
value = false;
|
||||
|
||||
if (result->second == "true")
|
||||
value = true;
|
||||
else if (result->second == "1")
|
||||
value = true;
|
||||
else if (result->second == "yes")
|
||||
value = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string CfgParser::get (const std::string& key, std::string defaultValue)
|
||||
{
|
||||
std::string value;
|
||||
|
||||
if (getString (key, value) == false)
|
||||
return defaultValue;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CfgParser::getString (const std::string& key, std::string& value)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator result;
|
||||
result = _Pairs.find (key);
|
||||
|
||||
if (result != _Pairs.end())
|
||||
{
|
||||
value = result->second;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CfgParser::getStrings (const std::string& key, std::vector<string>& strings)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator result;
|
||||
result = _Pairs.find (key);
|
||||
|
||||
if (result != _Pairs.end())
|
||||
{
|
||||
explode (result->second, strings, true, ",");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace BlueCore
|
||||
|
39
engine/Utilities/CfgParser.h
Normal file
39
engine/Utilities/CfgParser.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef BLUECORE_UTILITIES_CFGPARSER
|
||||
#define BLUECORE_UTILITIES_CFGPARSER
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace BlueCore {
|
||||
|
||||
class CfgParser
|
||||
{
|
||||
public:
|
||||
void parseFile (const std::string& filename);
|
||||
void parseLine (const std::string& line);
|
||||
void parse (const char* buffer, unsigned int length);
|
||||
|
||||
double get (const std::string& key, double value = 0.0);
|
||||
bool getDouble (const std::string& key, double& defaultValue);
|
||||
|
||||
int get (const std::string& key, int value = 0);
|
||||
bool getInteger (const std::string& key, int& defaultValue);
|
||||
|
||||
bool get (const std::string& key, bool value = false);
|
||||
bool getBoolean (const std::string& key, bool& defaultValue);
|
||||
|
||||
std::string get (const std::string& key, std::string value = "");
|
||||
bool getString (const std::string& key, std::string& defaultValue);
|
||||
|
||||
bool getStrings (const std::string& key, std::vector<std::string>& strings);
|
||||
|
||||
private:
|
||||
|
||||
std::map<std::string, std::string> _Pairs;
|
||||
};
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif
|
||||
|
11
engine/Utilities/IniParser.h
Normal file
11
engine/Utilities/IniParser.h
Normal file
@ -0,0 +1,11 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
class IniParser
|
||||
{
|
||||
std::map<std::string, std::string> _Pairs;
|
||||
|
||||
void parse (const std::string &text)
|
||||
{
|
||||
}
|
||||
}
|
82
engine/Utilities/Kernel.cpp
Normal file
82
engine/Utilities/Kernel.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include "Kernel.h"
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
Kernel::Kernel() :
|
||||
_Changed(true), _Clear(false)
|
||||
{
|
||||
}
|
||||
|
||||
void Kernel::addTask(KernelTask* task, int priority)
|
||||
{
|
||||
_AddedTasks.push_back(KernelTaskContainer (task, priority));
|
||||
_Changed = true;
|
||||
}
|
||||
|
||||
void Kernel::removeTask(KernelTask* task)
|
||||
{
|
||||
_RemovedTasks.push_back(task );
|
||||
_Changed = true;
|
||||
}
|
||||
|
||||
void Kernel::removeAllTasks()
|
||||
{
|
||||
_Clear = true;
|
||||
}
|
||||
|
||||
void Kernel::setTaskPriority(KernelTask* task, int priority)
|
||||
{
|
||||
std::list<KernelTaskContainer>::iterator i;
|
||||
for (i = _Tasks.begin(); i != _Tasks.end(); i++)
|
||||
{
|
||||
if ((*i)._Task.get() == task)
|
||||
{
|
||||
(*i)._Priority = priority;
|
||||
_Changed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Kernel::tick()
|
||||
{
|
||||
if (_Changed)
|
||||
{
|
||||
std::list<KernelTaskContainer>::iterator i;
|
||||
for (i = _AddedTasks.begin(); i != _AddedTasks.end(); i++)
|
||||
{
|
||||
_Tasks.push_back( *i );
|
||||
}
|
||||
|
||||
_AddedTasks.clear();
|
||||
_RemovedTasks.clear();
|
||||
_Tasks.sort();
|
||||
_Changed = false;
|
||||
}
|
||||
|
||||
std::list<KernelTaskContainer>::iterator i = _Tasks.begin();
|
||||
std::list<KernelTaskContainer>::iterator end = _Tasks.end();
|
||||
|
||||
if (i == end)
|
||||
return false;
|
||||
|
||||
while (i != end)
|
||||
{
|
||||
if ((*i)._Task.valid())
|
||||
(*i)._Task->tick();
|
||||
i++;
|
||||
}
|
||||
|
||||
if (_Clear)
|
||||
{
|
||||
_Tasks.clear();
|
||||
_Clear = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace BlueCore
|
||||
|
83
engine/Utilities/Kernel.h
Normal file
83
engine/Utilities/Kernel.h
Normal file
@ -0,0 +1,83 @@
|
||||
#ifndef KERNEL_H_
|
||||
#define KERNEL_H_
|
||||
|
||||
#include "Referenced.h"
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <list>
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
class Kernel;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class KernelTask : public Referenced
|
||||
{
|
||||
protected:
|
||||
|
||||
~KernelTask()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
KernelTask()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void tick()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class Kernel : public Referenced
|
||||
{
|
||||
private:
|
||||
|
||||
struct KernelTaskContainer
|
||||
{
|
||||
ref_ptr<KernelTask> _Task;
|
||||
int _Priority;
|
||||
|
||||
KernelTaskContainer(KernelTask* task, int priority) :
|
||||
_Task(task), _Priority(priority)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator <(const KernelTaskContainer& other) const
|
||||
{
|
||||
return (_Priority > other._Priority);
|
||||
}
|
||||
};
|
||||
|
||||
std::list<KernelTaskContainer> _Tasks;
|
||||
std::list<KernelTaskContainer> _AddedTasks;
|
||||
std::list<KernelTask*> _RemovedTasks;
|
||||
bool _Changed;
|
||||
bool _Clear;
|
||||
|
||||
protected:
|
||||
|
||||
~Kernel()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Kernel();
|
||||
|
||||
void addTask(KernelTask* task, int priority);
|
||||
void removeTask(KernelTask* task);
|
||||
void removeAllTasks();
|
||||
void setTaskPriority(KernelTask* task, int priority);
|
||||
bool tick();
|
||||
};
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif /*KERNEL_H_*/
|
||||
|
75
engine/Utilities/Log.cpp
Normal file
75
engine/Utilities/Log.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include "Log.h"
|
||||
#include <ctime>
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
//--------------------------------------------------------------------------
|
||||
Log::Log() :
|
||||
_LogFilename( "log.txt" )
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Log::reset()
|
||||
{
|
||||
std::ifstream testfile( _LogFilename.c_str() );
|
||||
if( testfile.is_open() )
|
||||
{
|
||||
testfile.close();
|
||||
_LogFile.open( _LogFilename.c_str(), std::ios::trunc );
|
||||
_LogFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Log::setFilename( const std::string &name )
|
||||
{
|
||||
_LogFilename = name;
|
||||
reset();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
Log &Log::operator << (const EndLine &e)
|
||||
{
|
||||
_LogFile << '\n';
|
||||
std::cout << '\n';
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
Log &Log::operator << (const EndLog &e)
|
||||
{
|
||||
_LogFile << '\n';
|
||||
_LogFile.close();
|
||||
std::cout << '\n';
|
||||
std::cout.flush();
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
Log &Log::operator << (const Time &t)
|
||||
{
|
||||
std::time_t rawtime;
|
||||
std::time ( &rawtime );
|
||||
char *tc = std::ctime( &rawtime );
|
||||
_LogFile << tc;
|
||||
std::cout << tc;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
Log &Log::operator << (const Flush &f)
|
||||
{
|
||||
_LogFile.close();
|
||||
std::cout.flush();
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
Log::EndLine endline;
|
||||
Log::EndLog endlog;
|
||||
Log::Time time;
|
||||
Log::Flush flush;
|
||||
Log clog;
|
||||
}
|
60
engine/Utilities/Log.h
Normal file
60
engine/Utilities/Log.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef BLUECORE_LOG_H
|
||||
#define BLUECORE_LOG_H
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
class Log
|
||||
{
|
||||
std::string _LogFilename;
|
||||
std::ofstream _LogFile;
|
||||
|
||||
public:
|
||||
class EndLine
|
||||
{
|
||||
};
|
||||
|
||||
class EndLog
|
||||
{
|
||||
};
|
||||
|
||||
class Time
|
||||
{
|
||||
};
|
||||
|
||||
class Flush
|
||||
{
|
||||
};
|
||||
|
||||
Log();
|
||||
|
||||
void setFilename( const std::string &name );
|
||||
void reset();
|
||||
|
||||
template<class T>
|
||||
Log &operator << (const T &v)
|
||||
{
|
||||
if( !_LogFile.is_open() )
|
||||
_LogFile.open(_LogFilename.c_str(), std::ios::app);
|
||||
_LogFile << v;
|
||||
std::cout << v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Log &operator << (const EndLine &e);
|
||||
Log &operator << (const EndLog &e);
|
||||
Log &operator << (const Time &t);
|
||||
Log &operator << (const Flush &f);
|
||||
};
|
||||
|
||||
extern Log::EndLine endline;
|
||||
extern Log::EndLog endlog;
|
||||
extern Log::Time time;
|
||||
extern Log::Flush flush;
|
||||
extern Log clog;
|
||||
|
||||
} // namespace bc
|
||||
|
||||
#endif // BLUECORE_LOG_H
|
423
engine/Utilities/MersenneTwister.h
Normal file
423
engine/Utilities/MersenneTwister.h
Normal file
@ -0,0 +1,423 @@
|
||||
// MersenneTwister.h
|
||||
// Mersenne Twister random number generator -- a C++ class MTRand
|
||||
// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
|
||||
// Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com
|
||||
|
||||
// The Mersenne Twister is an algorithm for generating random numbers. It
|
||||
// was designed with consideration of the flaws in various other generators.
|
||||
// The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
|
||||
// are far greater. The generator is also fast; it avoids multiplication and
|
||||
// division, and it benefits from caches and pipelines. For more information
|
||||
// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
|
||||
|
||||
// Reference
|
||||
// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
|
||||
// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
|
||||
// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
|
||||
|
||||
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||
// Copyright (C) 2000 - 2003, Richard J. Wagner
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. The names of its contributors may not be used to endorse or promote
|
||||
// products derived from this software without specific prior written
|
||||
// permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// The original code included the following notice:
|
||||
//
|
||||
// When you use this, send an email to: matumoto@math.keio.ac.jp
|
||||
// with an appropriate reference to your work.
|
||||
//
|
||||
// It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu
|
||||
// when you write.
|
||||
|
||||
#ifndef MERSENNETWISTER_H
|
||||
#define MERSENNETWISTER_H
|
||||
|
||||
// Not thread safe (unless auto-initialization is avoided and each thread has
|
||||
// its own MTRand object)
|
||||
|
||||
#include <iostream>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
class MTRand {
|
||||
// Data
|
||||
public:
|
||||
typedef unsigned long uint32; // unsigned integer type, at least 32 bits
|
||||
|
||||
enum { N = 624 }; // length of state vector
|
||||
enum { SAVE = N + 1 }; // length of array for save()
|
||||
|
||||
protected:
|
||||
enum { M = 397 }; // period parameter
|
||||
|
||||
uint32 state[N]; // internal state
|
||||
uint32 *pNext; // next value to get from state
|
||||
int left; // number of values left before reload needed
|
||||
|
||||
|
||||
//Methods
|
||||
public:
|
||||
MTRand( const uint32& oneSeed ); // initialize with a simple uint32
|
||||
MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array
|
||||
MTRand(); // auto-initialize with /dev/urandom or time() and clock()
|
||||
|
||||
// Do NOT use for CRYPTOGRAPHY without securely hashing several returned
|
||||
// values together, otherwise the generator state can be learned after
|
||||
// reading 624 consecutive values.
|
||||
|
||||
// Access to 32-bit random numbers
|
||||
double rand(); // real number in [0,1]
|
||||
double rand( const double& n ); // real number in [0,n]
|
||||
double randExc(); // real number in [0,1)
|
||||
double randExc( const double& n ); // real number in [0,n)
|
||||
double randDblExc(); // real number in (0,1)
|
||||
double randDblExc( const double& n ); // real number in (0,n)
|
||||
uint32 randInt(); // integer in [0,2^32-1]
|
||||
uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32
|
||||
double operator()() { return rand(); } // same as rand()
|
||||
|
||||
// Access to 53-bit random numbers (capacity of IEEE double precision)
|
||||
double rand53(); // real number in [0,1)
|
||||
|
||||
// Access to nonuniform random number distributions
|
||||
double randNorm( const double& mean = 0.0, const double& variance = 0.0 );
|
||||
|
||||
// Re-seeding functions with same behavior as initializers
|
||||
void seed( const uint32 oneSeed );
|
||||
void seed( uint32 *const bigSeed, const uint32 seedLength = N );
|
||||
void seed();
|
||||
|
||||
// Saving and loading generator state
|
||||
void save( uint32* saveArray ) const; // to array of size SAVE
|
||||
void load( uint32 *const loadArray ); // from such array
|
||||
friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand );
|
||||
friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
|
||||
|
||||
protected:
|
||||
void initialize( const uint32 oneSeed );
|
||||
void reload();
|
||||
uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
|
||||
uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
|
||||
uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
|
||||
uint32 mixBits( const uint32& u, const uint32& v ) const
|
||||
{ return hiBit(u) | loBits(v); }
|
||||
uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
|
||||
{ return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); }
|
||||
static uint32 hash( time_t t, clock_t c );
|
||||
};
|
||||
|
||||
|
||||
inline MTRand::MTRand( const uint32& oneSeed )
|
||||
{ seed(oneSeed); }
|
||||
|
||||
inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
|
||||
{ seed(bigSeed,seedLength); }
|
||||
|
||||
inline MTRand::MTRand()
|
||||
{ seed(); }
|
||||
|
||||
inline double MTRand::rand()
|
||||
{ return double(randInt()) * (1.0/4294967295.0); }
|
||||
|
||||
inline double MTRand::rand( const double& n )
|
||||
{ return rand() * n; }
|
||||
|
||||
inline double MTRand::randExc()
|
||||
{ return double(randInt()) * (1.0/4294967296.0); }
|
||||
|
||||
inline double MTRand::randExc( const double& n )
|
||||
{ return randExc() * n; }
|
||||
|
||||
inline double MTRand::randDblExc()
|
||||
{ return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
|
||||
|
||||
inline double MTRand::randDblExc( const double& n )
|
||||
{ return randDblExc() * n; }
|
||||
|
||||
inline double MTRand::rand53()
|
||||
{
|
||||
uint32 a = randInt() >> 5, b = randInt() >> 6;
|
||||
return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada
|
||||
}
|
||||
|
||||
inline double MTRand::randNorm( const double& mean, const double& variance )
|
||||
{
|
||||
// Return a real number from a normal (Gaussian) distribution with given
|
||||
// mean and variance by Box-Muller method
|
||||
double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
|
||||
double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
|
||||
return mean + r * cos(phi);
|
||||
}
|
||||
|
||||
inline MTRand::uint32 MTRand::randInt()
|
||||
{
|
||||
// Pull a 32-bit integer from the generator state
|
||||
// Every other access function simply transforms the numbers extracted here
|
||||
|
||||
if( left == 0 ) reload();
|
||||
--left;
|
||||
|
||||
register uint32 s1;
|
||||
s1 = *pNext++;
|
||||
s1 ^= (s1 >> 11);
|
||||
s1 ^= (s1 << 7) & 0x9d2c5680UL;
|
||||
s1 ^= (s1 << 15) & 0xefc60000UL;
|
||||
return ( s1 ^ (s1 >> 18) );
|
||||
}
|
||||
|
||||
inline MTRand::uint32 MTRand::randInt( const uint32& n )
|
||||
{
|
||||
// Find which bits are used in n
|
||||
// Optimized by Magnus Jonsson (magnus@smartelectronix.com)
|
||||
uint32 used = n;
|
||||
used |= used >> 1;
|
||||
used |= used >> 2;
|
||||
used |= used >> 4;
|
||||
used |= used >> 8;
|
||||
used |= used >> 16;
|
||||
|
||||
// Draw numbers until one is found in [0,n]
|
||||
uint32 i;
|
||||
do
|
||||
i = randInt() & used; // toss unused bits to shorten search
|
||||
while( i > n );
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
inline void MTRand::seed( const uint32 oneSeed )
|
||||
{
|
||||
// Seed the generator with a simple uint32
|
||||
initialize(oneSeed);
|
||||
reload();
|
||||
}
|
||||
|
||||
|
||||
inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
|
||||
{
|
||||
// Seed the generator with an array of uint32's
|
||||
// There are 2^19937-1 possible initial states. This function allows
|
||||
// all of those to be accessed by providing at least 19937 bits (with a
|
||||
// default seed length of N = 624 uint32's). Any bits above the lower 32
|
||||
// in each element are discarded.
|
||||
// Just call seed() if you want to get array from /dev/urandom
|
||||
initialize(19650218UL);
|
||||
register int i = 1;
|
||||
register uint32 j = 0;
|
||||
register int k = ( N > seedLength ? N : seedLength );
|
||||
for( ; k; --k )
|
||||
{
|
||||
state[i] =
|
||||
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
|
||||
state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
|
||||
state[i] &= 0xffffffffUL;
|
||||
++i; ++j;
|
||||
if( i >= N ) { state[0] = state[N-1]; i = 1; }
|
||||
if( j >= seedLength ) j = 0;
|
||||
}
|
||||
for( k = N - 1; k; --k )
|
||||
{
|
||||
state[i] =
|
||||
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
|
||||
state[i] -= i;
|
||||
state[i] &= 0xffffffffUL;
|
||||
++i;
|
||||
if( i >= N ) { state[0] = state[N-1]; i = 1; }
|
||||
}
|
||||
state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array
|
||||
reload();
|
||||
}
|
||||
|
||||
|
||||
inline void MTRand::seed()
|
||||
{
|
||||
// Seed the generator with an array from /dev/urandom if available
|
||||
// Otherwise use a hash of time() and clock() values
|
||||
|
||||
// First try getting an array from /dev/urandom
|
||||
FILE* urandom = fopen( "/dev/urandom", "rb" );
|
||||
if( urandom )
|
||||
{
|
||||
uint32 bigSeed[N];
|
||||
register uint32 *s = bigSeed;
|
||||
register int i = N;
|
||||
register bool success = true;
|
||||
while( success && i-- )
|
||||
success = fread( s++, sizeof(uint32), 1, urandom );
|
||||
fclose(urandom);
|
||||
if( success ) { seed( bigSeed, N ); return; }
|
||||
}
|
||||
|
||||
// Was not successful, so use time() and clock() instead
|
||||
seed( hash( time(NULL), clock() ) );
|
||||
}
|
||||
|
||||
|
||||
inline void MTRand::initialize( const uint32 seed )
|
||||
{
|
||||
// Initialize generator state with seed
|
||||
// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
|
||||
// In previous versions, most significant bits (MSBs) of the seed affect
|
||||
// only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
|
||||
register uint32 *s = state;
|
||||
register uint32 *r = state;
|
||||
register int i = 1;
|
||||
*s++ = seed & 0xffffffffUL;
|
||||
for( ; i < N; ++i )
|
||||
{
|
||||
*s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
|
||||
r++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void MTRand::reload()
|
||||
{
|
||||
// Generate N new values in state
|
||||
// Made clearer and faster by Matthew Bellew (matthew.bellew@home.com)
|
||||
register uint32 *p = state;
|
||||
register int i;
|
||||
for( i = N - M; i--; ++p )
|
||||
*p = twist( p[M], p[0], p[1] );
|
||||
for( i = M; --i; ++p )
|
||||
*p = twist( p[M-N], p[0], p[1] );
|
||||
*p = twist( p[M-N], p[0], state[0] );
|
||||
|
||||
left = N, pNext = state;
|
||||
}
|
||||
|
||||
|
||||
inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
|
||||
{
|
||||
// Get a uint32 from t and c
|
||||
// Better than uint32(x) in case x is floating point in [0,1]
|
||||
// Based on code by Lawrence Kirby (fred@genesis.demon.co.uk)
|
||||
|
||||
static uint32 differ = 0; // guarantee time-based seeds will change
|
||||
|
||||
uint32 h1 = 0;
|
||||
unsigned char *p = (unsigned char *) &t;
|
||||
for( size_t i = 0; i < sizeof(t); ++i )
|
||||
{
|
||||
h1 *= UCHAR_MAX + 2U;
|
||||
h1 += p[i];
|
||||
}
|
||||
uint32 h2 = 0;
|
||||
p = (unsigned char *) &c;
|
||||
for( size_t j = 0; j < sizeof(c); ++j )
|
||||
{
|
||||
h2 *= UCHAR_MAX + 2U;
|
||||
h2 += p[j];
|
||||
}
|
||||
return ( h1 + differ++ ) ^ h2;
|
||||
}
|
||||
|
||||
|
||||
inline void MTRand::save( uint32* saveArray ) const
|
||||
{
|
||||
register uint32 *sa = saveArray;
|
||||
register const uint32 *s = state;
|
||||
register int i = N;
|
||||
for( ; i--; *sa++ = *s++ ) {}
|
||||
*sa = left;
|
||||
}
|
||||
|
||||
|
||||
inline void MTRand::load( uint32 *const loadArray )
|
||||
{
|
||||
register uint32 *s = state;
|
||||
register uint32 *la = loadArray;
|
||||
register int i = N;
|
||||
for( ; i--; *s++ = *la++ ) {}
|
||||
left = *la;
|
||||
pNext = &state[N-left];
|
||||
}
|
||||
|
||||
|
||||
inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand )
|
||||
{
|
||||
register const MTRand::uint32 *s = mtrand.state;
|
||||
register int i = mtrand.N;
|
||||
for( ; i--; os << *s++ << "\t" ) {}
|
||||
return os << mtrand.left;
|
||||
}
|
||||
|
||||
|
||||
inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
|
||||
{
|
||||
register MTRand::uint32 *s = mtrand.state;
|
||||
register int i = mtrand.N;
|
||||
for( ; i--; is >> *s++ ) {}
|
||||
is >> mtrand.left;
|
||||
mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
|
||||
return is;
|
||||
}
|
||||
|
||||
#endif // MERSENNETWISTER_H
|
||||
|
||||
// Change log:
|
||||
//
|
||||
// v0.1 - First release on 15 May 2000
|
||||
// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
|
||||
// - Translated from C to C++
|
||||
// - Made completely ANSI compliant
|
||||
// - Designed convenient interface for initialization, seeding, and
|
||||
// obtaining numbers in default or user-defined ranges
|
||||
// - Added automatic seeding from /dev/urandom or time() and clock()
|
||||
// - Provided functions for saving and loading generator state
|
||||
//
|
||||
// v0.2 - Fixed bug which reloaded generator one step too late
|
||||
//
|
||||
// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
|
||||
//
|
||||
// v0.4 - Removed trailing newline in saved generator format to be consistent
|
||||
// with output format of built-in types
|
||||
//
|
||||
// v0.5 - Improved portability by replacing static const int's with enum's and
|
||||
// clarifying return values in seed(); suggested by Eric Heimburg
|
||||
// - Removed MAXINT constant; use 0xffffffffUL instead
|
||||
//
|
||||
// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
|
||||
// - Changed integer [0,n] generator to give better uniformity
|
||||
//
|
||||
// v0.7 - Fixed operator precedence ambiguity in reload()
|
||||
// - Added access for real numbers in (0,1) and (0,n)
|
||||
//
|
||||
// v0.8 - Included time.h header to properly support time_t and clock_t
|
||||
//
|
||||
// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
|
||||
// - Allowed for seeding with arrays of any length
|
||||
// - Added access for real numbers in [0,1) with 53-bit resolution
|
||||
// - Added access for real numbers from normal (Gaussian) distributions
|
||||
// - Increased overall speed by optimizing twist()
|
||||
// - Doubled speed of integer [0,n] generation
|
||||
// - Fixed out-of-range number generation on 64-bit machines
|
||||
// - Improved portability by substituting literal constants for long enum's
|
||||
// - Changed license from GNU LGPL to BSD
|
64
engine/Utilities/Named.h
Normal file
64
engine/Utilities/Named.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef BLUECORE_NAMED_H
|
||||
#define BLUECORE_NAMED_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
class Named
|
||||
{
|
||||
private:
|
||||
|
||||
std::string _Name;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
inline Named() :
|
||||
_Name( "" )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param strName set initial name
|
||||
*/
|
||||
inline Named( const std::string &name ) :
|
||||
_Name( name )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual inline ~Named()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the name.
|
||||
* @return returns the name
|
||||
*/
|
||||
inline const std::string &getName() const
|
||||
{
|
||||
return _Name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the name.
|
||||
*/
|
||||
inline void setName( const std::string &name )
|
||||
{
|
||||
_Name = name;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
236
engine/Utilities/Referenced.h
Normal file
236
engine/Utilities/Referenced.h
Normal file
@ -0,0 +1,236 @@
|
||||
#ifndef BLUECORE_REFERENCED_COUNTER_H
|
||||
#define BLUECORE_REFERENCED_COUNTER_H
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace BlueCore
|
||||
{
|
||||
|
||||
class Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
class DestructionListener
|
||||
{
|
||||
public:
|
||||
virtual void onDestruction(Referenced *referenced) = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
std::list<DestructionListener*> _DestructionListeners;
|
||||
|
||||
unsigned int _ReferenceCount;
|
||||
|
||||
virtual void destroyReferenced()
|
||||
{
|
||||
while (_DestructionListeners.begin() != _DestructionListeners.end())
|
||||
{
|
||||
if (_DestructionListeners.front() != 0)
|
||||
_DestructionListeners.front()->onDestruction(this);
|
||||
_DestructionListeners.pop_front();
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
inline Referenced() :
|
||||
_ReferenceCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual inline ~Referenced()
|
||||
{
|
||||
}
|
||||
|
||||
inline void addReference()
|
||||
{
|
||||
_ReferenceCount += 1;
|
||||
}
|
||||
|
||||
inline void removeReference()
|
||||
{
|
||||
if (_ReferenceCount > 0)
|
||||
{
|
||||
_ReferenceCount -= 1;
|
||||
|
||||
if ( 0 == _ReferenceCount)
|
||||
{
|
||||
destroyReferenced();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline unsigned int getReferenceCount()
|
||||
{
|
||||
return _ReferenceCount;
|
||||
}
|
||||
|
||||
inline void addDestructionListener(DestructionListener *listener)
|
||||
{
|
||||
if (listener != 0)
|
||||
_DestructionListeners.push_back(listener);
|
||||
}
|
||||
|
||||
inline void removeDestructionListener(DestructionListener *listener)
|
||||
{
|
||||
_DestructionListeners.remove(listener);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> class ref_ptr
|
||||
{
|
||||
public:
|
||||
ref_ptr() :
|
||||
_Referenced(0)
|
||||
{
|
||||
}
|
||||
|
||||
ref_ptr(T* referenced) :
|
||||
_Referenced(referenced)
|
||||
{
|
||||
if (_Referenced)
|
||||
_Referenced->addReference();
|
||||
}
|
||||
|
||||
ref_ptr(const ref_ptr& op) :
|
||||
_Referenced(op._Referenced)
|
||||
{
|
||||
if (_Referenced)
|
||||
_Referenced->addReference();
|
||||
}
|
||||
|
||||
~ref_ptr()
|
||||
{
|
||||
if (_Referenced)
|
||||
_Referenced->removeReference();
|
||||
}
|
||||
|
||||
T* operator ->() const
|
||||
{
|
||||
return _Referenced;
|
||||
}
|
||||
|
||||
ref_ptr& operator =(T* op)
|
||||
{
|
||||
if (op != _Referenced)
|
||||
{
|
||||
if (_Referenced != 0)
|
||||
_Referenced->removeReference();
|
||||
|
||||
_Referenced = op;
|
||||
|
||||
if (_Referenced)
|
||||
_Referenced->addReference();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator ==(const ref_ptr& ref)
|
||||
{
|
||||
if (_Referenced == ref._Referenced)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool valid() const
|
||||
{
|
||||
return (_Referenced != 0);
|
||||
}
|
||||
|
||||
operator T*() const
|
||||
{
|
||||
return _Referenced;
|
||||
}
|
||||
|
||||
T* get() const
|
||||
{
|
||||
return _Referenced;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T* _Referenced;
|
||||
};
|
||||
|
||||
template<class T> class weak_ptr : public Referenced::DestructionListener
|
||||
{
|
||||
public:
|
||||
weak_ptr() :
|
||||
_Referenced(0)
|
||||
{
|
||||
}
|
||||
|
||||
weak_ptr(T* referenced) :
|
||||
_Referenced(referenced)
|
||||
{
|
||||
if (_Referenced)
|
||||
_Referenced->addDestructionListener(this);
|
||||
}
|
||||
|
||||
weak_ptr(const weak_ptr& op) :
|
||||
_Referenced(op._Referenced)
|
||||
{
|
||||
if (_Referenced)
|
||||
_Referenced->addDestructionListener(this);
|
||||
}
|
||||
|
||||
virtual ~weak_ptr()
|
||||
{
|
||||
if (_Referenced)
|
||||
_Referenced->removeDestructionListener(this);
|
||||
}
|
||||
|
||||
T* operator ->() const
|
||||
{
|
||||
return _Referenced;
|
||||
}
|
||||
|
||||
weak_ptr& operator =(T* op)
|
||||
{
|
||||
if (op != _Referenced && _Referenced != 0)
|
||||
_Referenced->removeDestructionListener(this);
|
||||
|
||||
_Referenced = op;
|
||||
_Referenced->addDestructionListener(this);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator ==(const weak_ptr& ref)
|
||||
{
|
||||
if (_Referenced == ref._Referenced)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool valid() const
|
||||
{
|
||||
return (_Referenced != 0);
|
||||
}
|
||||
|
||||
|
||||
T* get() const
|
||||
{
|
||||
return _Referenced;
|
||||
}
|
||||
|
||||
|
||||
void onDestruction(Referenced *referenced)
|
||||
{
|
||||
_Referenced = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T* _Referenced;
|
||||
};
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif
|
119
engine/Utilities/StringUtilities.h
Normal file
119
engine/Utilities/StringUtilities.h
Normal file
@ -0,0 +1,119 @@
|
||||
#ifndef BLUECORE_STRING_UTILITIES_H
|
||||
#define BLUECORE_STRING_UTILITIES_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace BlueCore {
|
||||
|
||||
|
||||
#define SPACES " \t\r\n"
|
||||
|
||||
|
||||
/**
|
||||
* Function to remove whitespaces from the end of the string.
|
||||
* @param s String to be trimmed.
|
||||
* @param t String containing whitespaces. Default: space, tab, carriage return and newline.
|
||||
*/
|
||||
inline std::string trim_right(
|
||||
const std::string &s,
|
||||
const std::string &t = SPACES )
|
||||
{
|
||||
std::string::size_type i (s.find_last_not_of (t));
|
||||
|
||||
if (i == std::string::npos)
|
||||
return "";
|
||||
else
|
||||
return std::string( s, 0, i );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Function to remove whitespaces from the beginning of the string.
|
||||
* @param s String to be trimmed.
|
||||
* @param t String containing whitespaces. Default: space, tab, carriage return and newline.
|
||||
*/
|
||||
inline std::string trim_left(
|
||||
const std::string &s,
|
||||
const std::string &t = SPACES )
|
||||
{
|
||||
return std::string( s, s.find_first_not_of(t) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function to remove whitespaces from the beginning and the end of the string.
|
||||
* @param s String to be trimmed.
|
||||
* @param t String containing whitespaces. Default: space, tab, carriage return and newline.
|
||||
*/
|
||||
inline std::string trim(
|
||||
const std::string &s,
|
||||
const std::string &t = SPACES )
|
||||
{
|
||||
std::string::size_type a = s.find_first_not_of(t), b = s.find_last_not_of(t);
|
||||
|
||||
if ( a == std::string::npos || b == std::string::npos )
|
||||
return "";
|
||||
|
||||
return std::string( s, a, b-a+1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Splits a string into pieces, and returns them in an array.
|
||||
* @param s String to be exploded.
|
||||
* @param v Vector which receives the pieces.
|
||||
* @param t String containing whitespaces. Default: space, tab, carriage return and newline.
|
||||
* @param trim_spaces Flag to decide if pieces should be trimmed. Default: false.
|
||||
*/
|
||||
inline void explode(
|
||||
const std::string &s,
|
||||
std::vector<std::string> &v,
|
||||
const bool trim_spaces = false,
|
||||
const std::string &t = SPACES )
|
||||
{
|
||||
std::string::size_type a, b;
|
||||
|
||||
a = s.find_first_not_of(t), b = s.find_first_of(t, a);
|
||||
|
||||
while( a != std::string::npos )
|
||||
{
|
||||
if( trim_spaces )
|
||||
v.push_back( trim( s.substr(a, b-a) ) );
|
||||
else
|
||||
v.push_back( s.substr(a, b-a) );
|
||||
|
||||
a = s.find_first_not_of(t, b), b = s.find_first_of(t, a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Function to assemble strings from a vector into one strng.
|
||||
* @param v Vector which conatins the string pieces.
|
||||
* @param t String which is places between peaces. Default: one space " ".
|
||||
* @return Assembled string.
|
||||
*/
|
||||
inline std::string implode(
|
||||
const std::vector<std::string> &v,
|
||||
const std::string &t = " " )
|
||||
{
|
||||
unsigned int i;
|
||||
std::string s;
|
||||
|
||||
for( i = 0; i < (v.size() - 1); i++)
|
||||
{
|
||||
s.append( v[i] );
|
||||
s.append( t );
|
||||
}
|
||||
|
||||
return s+v[i];
|
||||
}
|
||||
|
||||
} // namespace BlueCore
|
||||
|
||||
#endif
|
142
engine/Utilities/format.cpp
Normal file
142
engine/Utilities/format.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
#include "format.h"
|
||||
|
||||
#ifndef NFORMAT
|
||||
|
||||
void Format::CFormat::reset()
|
||||
{
|
||||
valid = false;
|
||||
adjust = RIGHT;
|
||||
special = false;
|
||||
precision = 6;
|
||||
precision_explicit = false;
|
||||
zero = false;
|
||||
sign = false;
|
||||
width = 0;
|
||||
internal = false;
|
||||
setupper = false;
|
||||
grouping = false;
|
||||
conversion = false;
|
||||
base = DEC;
|
||||
floating = FIXED;
|
||||
showbase = false;
|
||||
strlength = 0;
|
||||
}
|
||||
|
||||
int Format::skip_atoi( std::string s, ST start, ST& pos )
|
||||
{
|
||||
pos = start;
|
||||
ST len = s.size();
|
||||
|
||||
while( (pos < len) && isdigit( s[pos] ) )
|
||||
pos++;
|
||||
|
||||
return atoi( s.substr( start, start-pos ).c_str() );
|
||||
}
|
||||
|
||||
void Format::CFormat::set( std::ostream& out )
|
||||
{
|
||||
if( !valid )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
printf( "valid: %d\n", valid );
|
||||
printf( "adjust: %d\n", adjust );
|
||||
printf( "special: %d\n", special );
|
||||
printf( "precision: %d\n", precision );
|
||||
printf( "precision_explicit: %d\n", precision_explicit );
|
||||
printf( "zero: %d\n", zero );
|
||||
printf( "sign: %d\n", sign );
|
||||
printf( "width: %d\n", width );
|
||||
printf( "internal: %d\n", internal );
|
||||
printf( "setupper: %d\n", setupper );
|
||||
printf( "grouping: %d\n", grouping );
|
||||
printf( "conversion: %d\n", conversion );
|
||||
printf( "base: %d\n", base );
|
||||
printf( "floating: %d\n", floating );
|
||||
printf( "showbase: %d\n", showbase );
|
||||
printf( "strlength: %d\n", strlength );
|
||||
*/
|
||||
|
||||
if( base == HEX && special && showbase && zero )
|
||||
{
|
||||
// without this correction:
|
||||
// printf( "[%#08x]", 0x42 ) => [0x000042]
|
||||
// fromat( "[%#08x]", 0x42 ) => [00000x42]
|
||||
|
||||
showbase = false;
|
||||
out << '0' << ( setupper ? 'X' : 'x' );
|
||||
width -= 2;
|
||||
}
|
||||
|
||||
if( base == HEX && special && showbase && strlength )
|
||||
{
|
||||
/*
|
||||
sprintf( buffer, "[%#8.3x]", 0x42 ) => [ 0x042]
|
||||
*/
|
||||
|
||||
showbase = false;
|
||||
|
||||
if( width )
|
||||
{
|
||||
for( int i = 0; i + strlength + 2 + 1 < width; ++i )
|
||||
out << ' ';
|
||||
width = 0;
|
||||
}
|
||||
|
||||
out << '0' << ( setupper ? 'X' : 'x' );
|
||||
for( int i = 0; i + strlength < precision; ++i )
|
||||
out << '0';
|
||||
}
|
||||
|
||||
if( adjust == LEFT && zero )
|
||||
{
|
||||
/*
|
||||
sprintf( buffer, "[%-#08x]", 0x42 ); => [0x42 ]
|
||||
not => [0x420000]
|
||||
*/
|
||||
zero = false;
|
||||
}
|
||||
|
||||
switch( adjust )
|
||||
{
|
||||
case LEFT: out.setf( std::ios::left, std::ios::adjustfield ); break;
|
||||
case RIGHT: out.setf( std::ios::right, std::ios::adjustfield ); break;
|
||||
}
|
||||
|
||||
if( zero ) out << std::setfill('0');
|
||||
else out << std::setfill( ' ' );
|
||||
|
||||
if( sign ) out.setf( std::ios::showpos );
|
||||
else out.unsetf( std::ios::showpos );
|
||||
|
||||
if( internal )
|
||||
out.setf( std::ios::internal, std::ios::adjustfield );
|
||||
|
||||
switch( base )
|
||||
{
|
||||
case OCT: out.setf( std::ios::oct, std::ios::basefield ); break;
|
||||
case DEC: out.setf( std::ios::dec, std::ios::basefield ); break;
|
||||
case HEX: out.setf( std::ios::hex, std::ios::basefield ); break;
|
||||
}
|
||||
|
||||
if( setupper ) out.setf( std::ios::uppercase );
|
||||
else out.unsetf( std::ios::uppercase );
|
||||
|
||||
switch( floating )
|
||||
{
|
||||
case FIXED: out.setf( std::ios::fixed, std::ios::floatfield ); break;
|
||||
case SCIENTIFIC: out.setf( std::ios::scientific, std::ios::floatfield ); break;
|
||||
}
|
||||
|
||||
if( showbase )
|
||||
out.setf( std::ios::showbase );
|
||||
else
|
||||
out.unsetf( std::ios::showbase );
|
||||
|
||||
out << std::setw( width );
|
||||
out << std::setprecision( precision );
|
||||
}
|
||||
|
||||
#endif
|
919
engine/Utilities/format.h
Normal file
919
engine/Utilities/format.h
Normal file
@ -0,0 +1,919 @@
|
||||
/*
|
||||
Format a C++ library for typesafe string formating in printf style
|
||||
(C) 2001 - 2003 by Martin Oberzalek <kingleo@gmx.at>
|
||||
|
||||
Examples:
|
||||
std::cout << format( "Hello %s, I have $05d$ in my pocket", "world", 5 ) << std::endl;
|
||||
std::cout << format( "Do not try this with printf: %s", 10101 ) << std::endl;
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef format_h
|
||||
#define format_h
|
||||
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
Can we use stringstreams or do we have to use the deprecated strstreams instead?
|
||||
If we have to use strstreams, simple comment the next #define
|
||||
**/
|
||||
#define HAVE_STL_SSTREAM
|
||||
#define NFORMAT
|
||||
|
||||
|
||||
#if __GNUC__ == 2
|
||||
#undef HAVE_STL_SSTREAM
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STL_SSTREAM
|
||||
# include <sstream>
|
||||
# include <cctype>
|
||||
# define IS_DIGIT( x ) std::isdigit( x )
|
||||
#else
|
||||
extern "C" {
|
||||
# include <ctype.h>
|
||||
}
|
||||
# include <strstream>
|
||||
# define IS_DIGIT( x ) isdigit( x )
|
||||
#endif
|
||||
|
||||
#ifndef NFORMAT
|
||||
|
||||
namespace Format
|
||||
{
|
||||
typedef std::string::size_type ST;
|
||||
|
||||
class CFormat
|
||||
{
|
||||
public:
|
||||
|
||||
typedef enum Adjust
|
||||
{
|
||||
LEFT,
|
||||
RIGHT
|
||||
};
|
||||
|
||||
typedef enum Base
|
||||
{
|
||||
OCT,
|
||||
DEC,
|
||||
HEX
|
||||
};
|
||||
|
||||
typedef enum Floating
|
||||
{
|
||||
FIXED,
|
||||
SCIENTIFIC
|
||||
};
|
||||
|
||||
bool valid;
|
||||
Adjust adjust;
|
||||
bool special;
|
||||
bool sign;
|
||||
bool grouping; // SUSv2 extension
|
||||
bool conversion; // glibc 2.2 extension
|
||||
bool zero;
|
||||
bool precision_explicit;
|
||||
bool internal;
|
||||
Base base;
|
||||
bool setupper;
|
||||
Floating floating;
|
||||
bool showbase;
|
||||
|
||||
int width;
|
||||
int precision;
|
||||
int strlength;
|
||||
|
||||
std::string format;
|
||||
|
||||
public:
|
||||
CFormat() { reset(); }
|
||||
|
||||
void set( std::ostream& out );
|
||||
|
||||
private:
|
||||
void reset();
|
||||
};
|
||||
|
||||
/****************************************/
|
||||
// all the errors that are thrown
|
||||
// are a cause of a mistake with %* or %*m$
|
||||
class Error
|
||||
{
|
||||
public:
|
||||
std::string err;
|
||||
Error( std::string s ) : err( s ) {}
|
||||
};
|
||||
|
||||
/****************************************/
|
||||
|
||||
template <class A, class B, class C, class D, class E, class F>
|
||||
class Format
|
||||
{
|
||||
private:
|
||||
struct Arg
|
||||
{
|
||||
bool is_int;
|
||||
bool is_string;
|
||||
};
|
||||
|
||||
Arg args[6];
|
||||
|
||||
std::string format;
|
||||
|
||||
A a;
|
||||
B b;
|
||||
C c;
|
||||
D d;
|
||||
E e;
|
||||
F f;
|
||||
|
||||
unsigned int num_of_args;
|
||||
|
||||
std::string s;
|
||||
|
||||
public:
|
||||
Format( const std::string &format, A a, B b, C c, D d, E e, F f, unsigned int num_of_args );
|
||||
|
||||
std::string get_string() const { return s; }
|
||||
|
||||
private:
|
||||
void parse();
|
||||
|
||||
template <class N> bool is_int( N &n ) { return false; }
|
||||
bool is_int( int &n ) { return true; }
|
||||
bool is_int( unsigned int &n ) { return true; }
|
||||
bool is_int( short &n ) { return true; }
|
||||
bool is_int( unsigned short ) { return true; }
|
||||
|
||||
template <class S> bool is_string( S &s ) { return false; }
|
||||
bool is_string( std::string& s ) { return true; }
|
||||
bool is_string( const std::string& s ) { return true; }
|
||||
bool is_string( char* ) { return true; }
|
||||
bool is_string( const char* ) { return true; }
|
||||
|
||||
int get_int_arg( unsigned int num );
|
||||
void gen_arg_list();
|
||||
std::string use_arg( unsigned int i, const CFormat &cf );
|
||||
|
||||
template <class S> std::string x2s( S ss, const CFormat &cf )
|
||||
{
|
||||
#ifdef HAVE_STL_SSTREAM
|
||||
std::stringstream str;
|
||||
str << cf << ss;
|
||||
std::string st = str.str();
|
||||
return st;
|
||||
#else
|
||||
std::strstream str;
|
||||
str << cf << ss << std::ends;
|
||||
std::string st = str.str();
|
||||
str.freeze(0);
|
||||
return st;
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int skip_atoi( std::string s, ST start, ST& pos );
|
||||
|
||||
} // namespace Format
|
||||
|
||||
inline std::ostream& operator<<( std::ostream& out, Format::CFormat cf )
|
||||
{
|
||||
cf.set( out );
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
template <class A, class B, class C, class D, class E, class F>
|
||||
Format::Format<A,B,C,D,E,F>::Format( std::string const &format, A a, B b, C c, D d, E e, F f, unsigned int num_of_args )
|
||||
: format( format ), a(a), b(b), c(c), d(d), e(e), f(f), num_of_args( num_of_args )
|
||||
{
|
||||
if( num_of_args > 6 )
|
||||
throw Error( "Number of args out of range" );
|
||||
|
||||
gen_arg_list();
|
||||
|
||||
parse();
|
||||
}
|
||||
|
||||
template <class A, class B, class C, class D, class E, class F>
|
||||
int Format::Format<A,B,C,D,E,F>::get_int_arg( unsigned int num )
|
||||
{
|
||||
if( static_cast<unsigned int>(num) > num_of_args - 1 )
|
||||
throw Error( "The arg you wan't to use is out of range" );
|
||||
|
||||
if( num < 0 )
|
||||
throw Error( "negativ number for arg number not allowed" );
|
||||
|
||||
if( args[num].is_int )
|
||||
{
|
||||
switch( num )
|
||||
{
|
||||
case 0: return *((int*) &a); // I have to cast here cause the compiler
|
||||
case 1: return *((int*) &b); // will make troubles if any of these
|
||||
case 2: return *((int*) &c); // values is not an unsigned int.
|
||||
case 3: return *((int*) &d); // Even if we are sure that
|
||||
case 4: return *((int*) &e); // an unsigned int value will be returned
|
||||
case 5: return *((int*) &f);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw Error( "expecting int arg" );
|
||||
|
||||
return 0; // should never be reached
|
||||
}
|
||||
|
||||
template <class A, class B, class C, class D, class E, class F>
|
||||
void Format::Format<A,B,C,D,E,F>::gen_arg_list()
|
||||
{
|
||||
for( unsigned int i = 0; i < num_of_args; i++ )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
case 0:
|
||||
args[i].is_int = is_int( a );
|
||||
args[i].is_string = is_string( a );
|
||||
break;
|
||||
case 1:
|
||||
args[i].is_int = is_int( b );
|
||||
args[i].is_string = is_string( b );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
args[i].is_int = is_int( c );
|
||||
args[i].is_string = is_string( c );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
args[i].is_int = is_int( d );
|
||||
args[i].is_string = is_string( d );
|
||||
break;
|
||||
|
||||
case 4:
|
||||
args[i].is_int = is_int( e );
|
||||
args[i].is_string = is_string( e );
|
||||
break;
|
||||
|
||||
case 5:
|
||||
args[i].is_int = is_int( f );
|
||||
args[i].is_string = is_string( f );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class A, class B, class C, class D, class E, class F>
|
||||
std::string Format::Format<A,B,C,D,E,F>::use_arg( unsigned int i, const CFormat &cf )
|
||||
{
|
||||
if( i > num_of_args || i < 0 )
|
||||
throw Error( "out of arg range" );
|
||||
|
||||
switch( i )
|
||||
{
|
||||
case 0: return x2s( a, cf );
|
||||
case 1: return x2s( b, cf );
|
||||
case 2: return x2s( c, cf );
|
||||
case 3: return x2s( d, cf );
|
||||
case 4: return x2s( e, cf );
|
||||
case 5: return x2s( f, cf );
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
template <class A, class B, class C, class D, class E, class F>
|
||||
void Format::Format<A,B,C,D,E,F>::parse()
|
||||
{
|
||||
if( format.empty() )
|
||||
return;
|
||||
|
||||
unsigned int par = 0;
|
||||
unsigned int use_par = 0;
|
||||
ST pos = 0;
|
||||
ST len = format.size();
|
||||
s = "";
|
||||
bool had_precision = false;
|
||||
|
||||
while( par < num_of_args && pos < len )
|
||||
{ // while
|
||||
|
||||
use_par = par;
|
||||
|
||||
if( pos >= len )
|
||||
break;
|
||||
|
||||
if( format[pos] != '%' )
|
||||
{
|
||||
s += format[pos];
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// % digit found
|
||||
pos++;
|
||||
|
||||
if( !(pos < len ) || (format[pos] == '%') )
|
||||
{
|
||||
// %% -> %
|
||||
s += format[pos];
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// format string found
|
||||
|
||||
ST start = pos - 1;
|
||||
CFormat f;
|
||||
|
||||
// process flags
|
||||
|
||||
while( (pos < len) )
|
||||
{
|
||||
bool finished = false;
|
||||
|
||||
switch( format[pos] )
|
||||
{
|
||||
case '-' : f.adjust = CFormat::LEFT; break;
|
||||
case '+' : f.sign = true; break;
|
||||
case ' ' : f.zero = false; break;
|
||||
case '#' : f.special = true; break;
|
||||
case '\'': f.grouping = true; break;
|
||||
case 'I' : f.conversion = true; break;
|
||||
case '0' : f.zero = true; break;
|
||||
default: finished = true; break;
|
||||
}
|
||||
|
||||
if( finished )
|
||||
break;
|
||||
|
||||
pos++;
|
||||
} // while( (pos < len) )
|
||||
|
||||
// get argument number
|
||||
if( pos < len )
|
||||
{
|
||||
// search for the $ digit
|
||||
unsigned int dp = pos;
|
||||
|
||||
while( dp < len && IS_DIGIT( format[dp] ) )
|
||||
dp++;
|
||||
|
||||
if( dp < len && format[dp] == '$' )
|
||||
{
|
||||
use_par = skip_atoi( format, pos, pos ) - 1;
|
||||
pos = dp + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// get field with
|
||||
if( pos < len )
|
||||
{
|
||||
if( IS_DIGIT( format[pos] ) )
|
||||
f.width = skip_atoi( format, pos, pos );
|
||||
else if( format[pos] == '*' )
|
||||
{
|
||||
pos++;
|
||||
|
||||
// search for the $ digit
|
||||
unsigned int dp = pos;
|
||||
|
||||
while( dp < len && IS_DIGIT( format[dp] ) )
|
||||
dp++;
|
||||
|
||||
if( dp < len && format[dp] == '$' )
|
||||
{
|
||||
f.width = get_int_arg( skip_atoi( format, pos, pos ) - 1 );
|
||||
// skip $ sign
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
f.width = get_int_arg( par );
|
||||
|
||||
if( use_par == par )
|
||||
use_par++;
|
||||
|
||||
par++;
|
||||
}
|
||||
|
||||
if( f.width < 0 )
|
||||
{
|
||||
f.width *= -1;
|
||||
f.adjust = CFormat::LEFT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// precision
|
||||
if( pos < len )
|
||||
{
|
||||
if( format[pos] == '.' )
|
||||
{
|
||||
pos++;
|
||||
if( !(pos < len) )
|
||||
return;
|
||||
|
||||
had_precision = true;
|
||||
|
||||
if( IS_DIGIT( format[pos] ) )
|
||||
f.precision = skip_atoi( format, pos, pos );
|
||||
else if( format[pos] == '*' )
|
||||
{
|
||||
pos++;
|
||||
|
||||
|
||||
// search for the $ digit
|
||||
unsigned int dp = pos;
|
||||
|
||||
while( dp < len && IS_DIGIT( format[dp] ) )
|
||||
dp++;
|
||||
|
||||
if( dp < len && format[dp] == '$' )
|
||||
{
|
||||
f.precision = get_int_arg( skip_atoi( format, pos, pos ) - 1 );
|
||||
// skip $ sign
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
f.precision = get_int_arg( par );
|
||||
|
||||
if( use_par == par )
|
||||
use_par++;
|
||||
|
||||
par++;
|
||||
}
|
||||
|
||||
if( f.precision == 0)
|
||||
f.precision_explicit = true;
|
||||
|
||||
if( f.precision < 0 )
|
||||
f.precision = 0;
|
||||
}
|
||||
else
|
||||
f.precision = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// lenght modifier
|
||||
/*
|
||||
they will be ignored
|
||||
cause we know the types of the parameter
|
||||
*/
|
||||
if( (pos < len) )
|
||||
{
|
||||
bool hh = false;
|
||||
bool ll = false;
|
||||
bool found = false;
|
||||
|
||||
switch( format[pos] )
|
||||
{
|
||||
case 'h': hh = true; found = true; break;
|
||||
case 'l': ll = true; found = true; break;
|
||||
case 'L':
|
||||
case 'q':
|
||||
case 'j':
|
||||
case 'z':
|
||||
case 't': found = true; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if(found )
|
||||
{
|
||||
pos++;
|
||||
|
||||
if( pos < len )
|
||||
if( hh == true )
|
||||
{
|
||||
if( format[pos] == 'h' )
|
||||
pos++;
|
||||
}
|
||||
else if( ll = true )
|
||||
if( format[pos] == 'l' )
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
// conversion specifier
|
||||
|
||||
if( pos < len )
|
||||
{
|
||||
bool invalid = false;
|
||||
switch( format[pos] )
|
||||
{
|
||||
case 'd':
|
||||
case 'i':
|
||||
f.base = CFormat::DEC;
|
||||
if( f.zero && (f.adjust != CFormat::LEFT) )
|
||||
f.internal = true;
|
||||
break;
|
||||
|
||||
case 'X': f.setupper = true;
|
||||
case 'x':
|
||||
f.base = CFormat::HEX;
|
||||
if( f.special )
|
||||
f.showbase = true;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
f.base = CFormat::OCT;
|
||||
if( f.special )
|
||||
f.showbase = true;
|
||||
break;
|
||||
|
||||
|
||||
case 'E':
|
||||
f.setupper = true;
|
||||
|
||||
case 'e':
|
||||
if( f.special )
|
||||
f.sign = true;
|
||||
f.floating = CFormat::SCIENTIFIC;
|
||||
break;
|
||||
|
||||
case 'F': // not supported
|
||||
case 'f':
|
||||
if( f.special )
|
||||
f.sign = true;
|
||||
f.floating = CFormat::FIXED;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if( f.zero )
|
||||
f.zero = false;
|
||||
break;
|
||||
|
||||
|
||||
// unsupported modifiers
|
||||
|
||||
|
||||
case 'G':
|
||||
case 'g':
|
||||
|
||||
case 'A':
|
||||
case 'a':
|
||||
|
||||
case 'c':
|
||||
|
||||
case 'C':
|
||||
case 'S':
|
||||
case 'P':
|
||||
case 'n': break;
|
||||
|
||||
default: invalid = true;
|
||||
}
|
||||
|
||||
if( !invalid )
|
||||
f.valid = true;
|
||||
}
|
||||
|
||||
if( f.valid )
|
||||
{
|
||||
std::string str;
|
||||
int upar = par;
|
||||
|
||||
if( use_par != par )
|
||||
upar = use_par;
|
||||
|
||||
if( f.base == CFormat::HEX && had_precision && f.special )
|
||||
{
|
||||
CFormat f2;
|
||||
f2.base = f.base;
|
||||
std::string s = use_arg( upar, f2 );
|
||||
f.strlength = s.size();
|
||||
// printf( "str: %s\n", s.c_str() );
|
||||
}
|
||||
|
||||
str = use_arg( upar, f );
|
||||
|
||||
// cut string
|
||||
if( had_precision && args[upar].is_string )
|
||||
str = str.substr( 0, f.precision );
|
||||
|
||||
s += str;
|
||||
|
||||
if( use_par == par )
|
||||
par++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy the invalid format string
|
||||
for( ST i = start; i<= pos; i++ )
|
||||
if( i < len )
|
||||
s += format[i];
|
||||
}
|
||||
|
||||
pos++;
|
||||
|
||||
} // while
|
||||
|
||||
if( pos < len )
|
||||
{
|
||||
while( pos < len )
|
||||
{
|
||||
s += format[pos];
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else // ifndef NFORMAT
|
||||
|
||||
/// converts anything to a string
|
||||
template<class T>std::string x2s( T what )
|
||||
{
|
||||
#ifdef HAVE_STL_SSTREAM
|
||||
|
||||
std::stringstream str;
|
||||
|
||||
str << what;
|
||||
std::string s( str.str() );
|
||||
return s;
|
||||
|
||||
#else
|
||||
|
||||
std::strstream str;
|
||||
|
||||
str << what << std::ends;
|
||||
|
||||
std::string s( str.str() );
|
||||
|
||||
str.freeze(0);
|
||||
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace Format
|
||||
{
|
||||
|
||||
template <class T> const char* convert( T t ) { return x2s( t ).c_str(); }
|
||||
|
||||
#define DEF( TYPE ) \
|
||||
inline TYPE convert( TYPE t ) { return t; }
|
||||
|
||||
DEF( unsigned )
|
||||
DEF( int )
|
||||
DEF( char )
|
||||
DEF( char* )
|
||||
DEF( const char* )
|
||||
DEF( short )
|
||||
DEF( double )
|
||||
DEF( float )
|
||||
DEF( long )
|
||||
|
||||
#undef DEF
|
||||
|
||||
|
||||
template<class A, class B, class C, class D, class E, class F>
|
||||
class Format
|
||||
{
|
||||
std::string s;
|
||||
|
||||
public:
|
||||
Format( const std::string &format, A a, B b, C c, D d, E e, F f, unsigned int num_of_args )
|
||||
{
|
||||
#define D( T ) convert( T )
|
||||
unsigned buffer_size = 256;
|
||||
|
||||
bool cont = false;
|
||||
|
||||
do {
|
||||
|
||||
cont = false;
|
||||
|
||||
char *buffer = new char[buffer_size];
|
||||
int n = 0;
|
||||
|
||||
switch( num_of_args )
|
||||
{
|
||||
case 1: n = std::sprintf( buffer, format.c_str(),
|
||||
D( a ) ); break;
|
||||
case 2: n = std::sprintf( buffer, format.c_str(),
|
||||
D( a ), D( b ) ); break;
|
||||
case 3: n = std::sprintf( buffer, format.c_str(),
|
||||
D( a ), D( b ), D( c ) ); break;
|
||||
case 4: n = std::sprintf( buffer, format.c_str(),
|
||||
D( a ), D( b ), D( c ), D( d ) ); break;
|
||||
case 5: n = std::sprintf( buffer, format.c_str(),
|
||||
D( a ), D( b ), D( c ), D( d ), D( e ) ); break;
|
||||
case 6: n = std::sprintf( buffer, format.c_str(),
|
||||
D( a ), D( b ), D( c ), D( d ), D( e ), D( f ) ); break;
|
||||
}
|
||||
|
||||
|
||||
if( (unsigned) n >= buffer_size - 2 )
|
||||
{
|
||||
buffer_size *= 2;
|
||||
cont = true;
|
||||
n = 0;
|
||||
}
|
||||
|
||||
for( int i = 0; i < n; i++ )
|
||||
s += buffer[i];
|
||||
|
||||
delete[] buffer;
|
||||
|
||||
} while( cont );
|
||||
#undef D
|
||||
}
|
||||
|
||||
std::string get_string() const { return s; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class A, class B, class C, class D, class E, class F>
|
||||
inline std::string format( std::string fs, A a, B b, C c, D d, E e, F f )
|
||||
{
|
||||
return Format::Format<A,B,C,D,E,F>( fs, a, b, c, d, e, f, 6).get_string();
|
||||
}
|
||||
|
||||
template <class A, class B, class C, class D, class E>
|
||||
inline std::string format( std::string fs, A a, B b, C c, D d, E e )
|
||||
{
|
||||
return Format::Format<A,B,C,D,E,char>( fs, a, b, c, d, e, 0, 5).get_string();
|
||||
}
|
||||
|
||||
template <class A, class B, class C, class D>
|
||||
inline std::string format( std::string fs, A a, B b, C c, D d)
|
||||
{
|
||||
return Format::Format<A,B,C,D,char,char>( fs, a, b, c, d, 0, 0, 4).get_string();
|
||||
}
|
||||
|
||||
template <class A, class B, class C>
|
||||
inline std::string format( std::string fs, A a, B b, C c )
|
||||
{
|
||||
return Format::Format<A,B,C,char,char,char>( fs, a, b, c, 0, 0, 0, 3).get_string();
|
||||
}
|
||||
|
||||
template <class A, class B>
|
||||
inline std::string format( std::string fs, A a, B b )
|
||||
{
|
||||
return Format::Format<A,B,char,char,char,char>( fs, a, b, 0, 0, 0, 0, 2).get_string();
|
||||
}
|
||||
|
||||
template <class A>
|
||||
inline std::string format( std::string fs, A a)
|
||||
{
|
||||
return Format::Format<A,char,char,char,char,char>( fs, a, 0, 0, 0, 0, 0, 1).get_string();
|
||||
}
|
||||
|
||||
|
||||
namespace Format
|
||||
{
|
||||
template<typename ostream> class PrintF
|
||||
{
|
||||
private:
|
||||
|
||||
int level;
|
||||
int dlevel;
|
||||
|
||||
int dmodule;
|
||||
int module;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
ostream &out;
|
||||
|
||||
public:
|
||||
|
||||
PrintF( ostream &out = std::cout, int module = -1, int debug_level = -1 )
|
||||
: level( debug_level ), dlevel( debug_level ),
|
||||
dmodule( module), module( module), out( out )
|
||||
{}
|
||||
|
||||
void set_debug_level( int dlevel_ ) { dlevel = dlevel_; }
|
||||
void set_module( int module_ ) { dmodule = module_; }
|
||||
|
||||
PrintF operator()( int module_ )
|
||||
{
|
||||
PrintF printf( *this );
|
||||
printf.module = module_;
|
||||
|
||||
return printf;
|
||||
}
|
||||
|
||||
PrintF operator[]( int level_ )
|
||||
{
|
||||
PrintF printf( *this );
|
||||
printf.level = level_;
|
||||
|
||||
return printf;
|
||||
}
|
||||
|
||||
template<typename T> PrintF& operator<<( const T &t )
|
||||
{
|
||||
if( check() )
|
||||
out << t;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// io manipulator overloading
|
||||
PrintF& operator<<(ostream& (*f)(ostream&))
|
||||
{
|
||||
if( check() )
|
||||
out << f;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
PrintF& operator()( std::string fs )
|
||||
{
|
||||
if( check() )
|
||||
out << fs;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<typename A> PrintF& operator()( std::string fs, const A &a )
|
||||
{
|
||||
if( check() )
|
||||
out << format( fs, a );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
PrintF& operator()( std::string fs, const A &a, const B &b )
|
||||
{
|
||||
if( check() )
|
||||
out << format( fs, a, b );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename A, typename B, typename C>
|
||||
PrintF& operator()( std::string fs, const A &a, const B &b, const C &c )
|
||||
{
|
||||
if( check() )
|
||||
out << format( fs, a, b, c );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename A, typename B, typename C, typename D>
|
||||
PrintF& operator()( std::string fs, const A &a, const B &b, const C &c, const D &d )
|
||||
{
|
||||
if( check() )
|
||||
out << format( fs, a, b, c, d );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename A, typename B, typename C, typename D, typename E>
|
||||
PrintF& operator()( std::string fs, const A &a, const B &b, const C &c, const D &d, const E &e )
|
||||
{
|
||||
if( check() )
|
||||
out << format( fs, a, b, c, d, e );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename A, typename B, typename C, typename D, typename E, typename F>
|
||||
PrintF& operator()( std::string fs, const A &a, const B &b, const C &c, const D &d, const E &e, const F &f )
|
||||
{
|
||||
if( check() )
|
||||
out << format( fs, a, b, c, d, e, f );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool check( int module, int level ) const
|
||||
{
|
||||
if( module == dmodule || dmodule == -1 )
|
||||
{
|
||||
if( dlevel == -1 )
|
||||
return true;
|
||||
|
||||
if( level <= dlevel )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool check() const { return check( module, level ); }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#undef IS_DIGIT
|
||||
|
||||
#endif
|
2567
engine/Utilities/sigslot.h
Normal file
2567
engine/Utilities/sigslot.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
engine/data/DejaVuSans.ttf
Normal file
BIN
engine/data/DejaVuSans.ttf
Normal file
Binary file not shown.
10
engine/data/ambient_color_emissive.frag
Normal file
10
engine/data/ambient_color_emissive.frag
Normal file
@ -0,0 +1,10 @@
|
||||
uniform sampler2D color_emissive_texture;
|
||||
|
||||
varying vec4 vertex_ambient;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texel = texture2D( color_emissive_texture, gl_TexCoord[0].xy );
|
||||
gl_FragColor = (texel * vertex_ambient) + (texel * texel.a);
|
||||
gl_FragColor.a = 1.0;
|
||||
}
|
2
engine/data/ambient_color_emissive.prog
Normal file
2
engine/data/ambient_color_emissive.prog
Normal file
@ -0,0 +1,2 @@
|
||||
vertex_shaders = ambient_color_emissive
|
||||
fragment_shaders = ambient_color_emissive
|
10
engine/data/ambient_color_emissive.vert
Normal file
10
engine/data/ambient_color_emissive.vert
Normal file
@ -0,0 +1,10 @@
|
||||
varying vec4 vertex_ambient;
|
||||
|
||||
void main()
|
||||
{
|
||||
/* Compute the diffuse, ambient and globalAmbient terms */
|
||||
vertex_ambient = gl_LightModel.ambient * gl_FrontMaterial.ambient;
|
||||
|
||||
gl_Position = ftransform();
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
}
|
BIN
engine/data/combat.zip
Normal file
BIN
engine/data/combat.zip
Normal file
Binary file not shown.
BIN
engine/data/image.png
Normal file
BIN
engine/data/image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
114
engine/data/main.nut
Normal file
114
engine/data/main.nut
Normal file
@ -0,0 +1,114 @@
|
||||
EntityList <- [];
|
||||
|
||||
class Entity
|
||||
{
|
||||
function tick (time)
|
||||
{
|
||||
}
|
||||
|
||||
function step (time)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
function onFrame (time)
|
||||
{
|
||||
for(local i = 0; i < EntityList.len();)
|
||||
{
|
||||
if( EntityList[i].tick( time ) == 1 )
|
||||
{
|
||||
EntityList.remove(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function onStep (time)
|
||||
{
|
||||
for(local i = 0; i < EntityList.len(); ++i )
|
||||
{
|
||||
EntityList[i].step( time )
|
||||
}
|
||||
}
|
||||
|
||||
class Asteroid extends Entity
|
||||
{
|
||||
rigidbody = null;
|
||||
trafonode = null;
|
||||
modelnode = null;
|
||||
|
||||
constructor()
|
||||
{
|
||||
rigidbody = RigidBody (this);
|
||||
rigidbody.addCollisionMesh ("asteroid.collision", 1000.0);
|
||||
|
||||
model = Model ("asteroid");
|
||||
|
||||
node = Node();
|
||||
node.setPositionProvider (rigidbody);
|
||||
node.setRenderProvider (model);
|
||||
|
||||
sprite = Sprite ("name");
|
||||
spritenode = Node (node);
|
||||
spritenode.setRenderProvider (sprite);
|
||||
spritenode.setRelativePosition (Vector(10.0, 0.0, 0.0));
|
||||
//pg = ParticleGenerator ("comettail");
|
||||
}
|
||||
|
||||
function setPosition( position )
|
||||
{
|
||||
rigidbody.setPosition( position );
|
||||
}
|
||||
}
|
||||
|
||||
font <- null;
|
||||
logo <- null;
|
||||
lastFPS <- 0;
|
||||
frameCount <- 0;
|
||||
FPS <- 1;
|
||||
body <- null;
|
||||
|
||||
function Initialize()
|
||||
{
|
||||
::font = Font ("DejaVuSans.ttf", 24, 1 );
|
||||
::logo = Image ("image.png", 0.0, 0.0, 1.0, 1.0);
|
||||
::body = RigidBody();
|
||||
|
||||
}
|
||||
|
||||
function OnFrame( delta )
|
||||
{
|
||||
::frameCount += 1
|
||||
::lastFPS += delta;
|
||||
|
||||
if (::lastFPS > 0.1)
|
||||
{
|
||||
::FPS = ::frameCount * 10;
|
||||
::frameCount = 0;
|
||||
::lastFPS -= 0.1;
|
||||
}
|
||||
|
||||
if (::FPS > 0)
|
||||
{
|
||||
local fps = "FPS: " + FPS + " / " + (1.0/::FPS)*1000.0 + " ms";
|
||||
::font.print( 10, 10, fps, 1, 1 );
|
||||
}
|
||||
// ::logo.draw (0.5, 0.5);
|
||||
|
||||
v <- ::body.getPosition();
|
||||
::font.print(10, 40, "Position: " + v.x + ", " + v.y + ", " + v.z, 1, 1 );
|
||||
}
|
||||
|
||||
function OnStep( delte )
|
||||
{
|
||||
::body.applyLocalForce( Vector(0.0, 0.0, 1.0) );
|
||||
}
|
||||
|
||||
function Shutdown()
|
||||
{
|
||||
}
|
||||
|
168
engine/main.cpp
Normal file
168
engine/main.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "RenderWindow.h"
|
||||
#include "RenderDevice.h"
|
||||
#include "FontManager.h"
|
||||
#include "MeshManager.h"
|
||||
#include "TextureManager.h"
|
||||
#include "ShaderManager.h"
|
||||
#include "ModelManager.h"
|
||||
#include "TextureImage.h"
|
||||
#include "ScriptSystem.h"
|
||||
#include "ScriptSystem_Font.h"
|
||||
#include "ScriptSystem_Image.h"
|
||||
#include "ScriptSystem_Math.h"
|
||||
#include "ScriptSystem_RigidBody.h"
|
||||
#include "RigidBodySimulation.h"
|
||||
|
||||
#include "Camera.h"
|
||||
#include "SceneNode.h"
|
||||
|
||||
#include "Utilities/CfgParser.h"
|
||||
#include "Utilities/Log.h"
|
||||
#include "Utilities/Kernel.h"
|
||||
|
||||
#include "physfs.h"
|
||||
|
||||
using namespace BlueCore;
|
||||
|
||||
void initializePhysfs(char* program)
|
||||
{
|
||||
// setup physfs
|
||||
PHYSFS_init(program);
|
||||
|
||||
std::string appdir = PHYSFS_getUserDir();
|
||||
appdir += ".bluecore";
|
||||
|
||||
if ( !PHYSFS_setWriteDir(appdir.c_str()) )
|
||||
{
|
||||
if ( (PHYSFS_setWriteDir(PHYSFS_getUserDir()))
|
||||
&& (PHYSFS_mkdir(".bluecore")))
|
||||
PHYSFS_setWriteDir(appdir.c_str() );
|
||||
}
|
||||
|
||||
PHYSFS_addToSearchPath(appdir.c_str(), 0);
|
||||
PHYSFS_addToSearchPath("data", 1);
|
||||
|
||||
char **rc = PHYSFS_enumerateFiles("");
|
||||
|
||||
for (char **i = rc; *i != 0; i++)
|
||||
{
|
||||
std::string filename( *i);
|
||||
|
||||
if (filename.substr(filename.size() - 4, 4) == ".zip")
|
||||
{
|
||||
PHYSFS_addToSearchPath(( "data/" + filename ).c_str(), 1);
|
||||
clog << ">>> Using addon: "<< filename << endlog;
|
||||
}
|
||||
}
|
||||
|
||||
PHYSFS_freeList(rc);
|
||||
}
|
||||
|
||||
void shutdownPhysfs()
|
||||
{
|
||||
PHYSFS_deinit();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
initializePhysfs(argv[0]);
|
||||
|
||||
CfgParser cfg;
|
||||
cfg.parseFile("options.cfg");
|
||||
|
||||
int width = cfg.get("width", 640);
|
||||
int height = cfg.get("height", 480);
|
||||
bool fullscreen = cfg.get("fullscreen", false);
|
||||
ref_ptr<RenderWindow> window = new RenderWindow();
|
||||
window->create(width, height, 0, 0, 0, fullscreen);
|
||||
|
||||
ref_ptr<RenderDevice> device = new RenderDevice(window);
|
||||
ref_ptr<FontManager> fontmanager = new FontManager(device);
|
||||
ref_ptr<MeshManager> meshmanager = new MeshManager(device);
|
||||
ref_ptr<TextureManager> texturemanager = new TextureManager();
|
||||
ref_ptr<ScriptSystem> scriptsystem = new ScriptSystem();
|
||||
ref_ptr<ShaderManager> shadermanager = new ShaderManager(window);
|
||||
ref_ptr<RigidBodySimulation> simulation = new RigidBodySimulation(scriptsystem);
|
||||
ref_ptr<ModelManager> modelmanager = new ModelManager (texturemanager, shadermanager, meshmanager);
|
||||
ref_ptr<Camera> camera = new Camera();
|
||||
|
||||
/*
|
||||
ShaderProgram prog =
|
||||
shadermanager->loadShaderProgram("ambient_color_emissive");
|
||||
*/
|
||||
setupScriptSystem_Font(scriptsystem, fontmanager);
|
||||
setupScriptSystem_Image(scriptsystem, texturemanager, device);
|
||||
setupScriptSystem_Math(scriptsystem);
|
||||
setupScriptSystem_RigidBody(scriptsystem, simulation);
|
||||
|
||||
GLfloat mat_specular[] =
|
||||
{ 1.0, 1.0, 1.0, 1.0 };
|
||||
GLfloat mat_shininess[] =
|
||||
{ 2.0 };
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_specular);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_specular);
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
|
||||
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
|
||||
|
||||
if (window.valid() && device.valid())
|
||||
{
|
||||
scriptsystem->loadScript("main");
|
||||
|
||||
camera->setFoV(90.0);
|
||||
camera->setAspectRatio((double)width/(double)height);
|
||||
camera->setNearPlane(1.0);
|
||||
camera->setFarPlane(100.0);
|
||||
camera->setPosition(Vector3(0.0, 0.0, 20.0));
|
||||
|
||||
device->setAmbientLight(1.0, 1.0, 1.0);
|
||||
|
||||
//ref_ptr<SceneNode> rootnode(new SceneNode("root node"));
|
||||
|
||||
double _DeltaTime = 0;
|
||||
double _LastTime = glfwGetTime();
|
||||
|
||||
ref_ptr<Model> model = modelmanager->loadModel("combat");
|
||||
scriptsystem->callFunction("Initialize");
|
||||
|
||||
clog << "--- starting main loop..."<< endlog;
|
||||
|
||||
while (window->isOpen())
|
||||
{
|
||||
device->clear();
|
||||
double time = glfwGetTime();
|
||||
_DeltaTime = time - _LastTime;
|
||||
_LastTime = time;
|
||||
|
||||
// device->setViewMatrix();
|
||||
// device->setProjectionMatrix();
|
||||
camera->setupProjectionMatrix();
|
||||
camera->setupViewMatrix();
|
||||
|
||||
// device->useShader (program);
|
||||
// device->setTexture (stage, name, texture)
|
||||
// device->clearTextures (stage+1);
|
||||
//glEnable (GL_TEXTURE_2D);
|
||||
//glEnable (GL_LIGHTING);
|
||||
//glBindTexture (GL_TEXTURE_2D, texture->getId() );
|
||||
|
||||
// device->
|
||||
model->render();
|
||||
|
||||
simulation->saveStates();
|
||||
simulation->updateSteps(_DeltaTime);
|
||||
while (simulation->step())
|
||||
;
|
||||
scriptsystem->callFunction("OnFrame", _DeltaTime);
|
||||
|
||||
window->swap();
|
||||
}
|
||||
|
||||
scriptsystem->callFunction("Shutdown");
|
||||
|
||||
clog << "--- main loop finished..."<< endlog;
|
||||
}
|
||||
|
||||
shutdownPhysfs();
|
||||
}
|
5
engine/options.cfg
Normal file
5
engine/options.cfg
Normal file
@ -0,0 +1,5 @@
|
||||
width = 800
|
||||
height = 600
|
||||
fullscreen = no
|
||||
|
||||
vertex_shader = bumbmapping sdsd sd sd
|
13
engine/todo.txt
Normal file
13
engine/todo.txt
Normal file
@ -0,0 +1,13 @@
|
||||
Addons
|
||||
------
|
||||
|
||||
* load addons in sorted order
|
||||
|
||||
Scripting
|
||||
---------
|
||||
|
||||
* make event based input available
|
||||
|
||||
* make ShaderProgram a class
|
||||
* create RenderSet AND/OR RenderQueue
|
||||
|
Reference in New Issue
Block a user