first commit
This commit is contained in:
82
include/framework/ascii/ascii_encoder.h
Normal file
82
include/framework/ascii/ascii_encoder.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NASCIIENC__
|
||||
#define __NASCIIENC__
|
||||
|
||||
|
||||
#include "ntypes.h"
|
||||
|
||||
|
||||
/*!
|
||||
@short ASCII encoding.
|
||||
|
||||
This class currently provide two commonly used encoding method:
|
||||
yEnc and UUEncode.
|
||||
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
namespace nAsciiEncoder
|
||||
{
|
||||
/*!
|
||||
@short Perform UUEncoding.
|
||||
|
||||
@param source Input binary stream.
|
||||
@param len Input binary stream length.
|
||||
@param uuenc Output buffer.
|
||||
@param max Output buffer length.
|
||||
@return The number of bytes written to the output buffer.
|
||||
|
||||
@note If yenc is NULL the function can be used to check the size
|
||||
of the encoded stream prior to allocating an output buffer.
|
||||
*/
|
||||
uint UUEncode(const uchar *source, size_t len, uchar *uuenc = 0, size_t max = 0);
|
||||
|
||||
/*!
|
||||
@short Perform UUDecoding.
|
||||
|
||||
@param source UUEncoded byte stream.
|
||||
@param len UUEncoded byte stream length.
|
||||
@param bin Output buffer.
|
||||
@param max Output buffer length.
|
||||
@return The number of bytes written to the output buffer.
|
||||
|
||||
@note If bin is NULL the function can be used to check the size
|
||||
of the decoded stream prior to allocating an output buffer.
|
||||
*/
|
||||
uint UUDecode(const uchar *source, size_t len, uchar *bin = 0, size_t max = 0);
|
||||
/*!
|
||||
@short Perform yEncoding.
|
||||
|
||||
@param source Input binary stream.
|
||||
@param len Input binary stream length.
|
||||
@param yenc Output buffer.
|
||||
@param max Output buffer length.
|
||||
@param line_len Number of character to output before a line-feed character is sent.
|
||||
@return The number of bytes written to the output buffer.
|
||||
|
||||
@note If yenc is NULL the function can be used to check the size
|
||||
of the encoded stream prior to allocating an output buffer.
|
||||
*/
|
||||
uint yEncode(const uchar *source, size_t len, uchar *yenc = 0, size_t max = 0, uint line_len = 64);
|
||||
|
||||
/*!
|
||||
@short Perform yDecoding.
|
||||
|
||||
@param source yEncoded byte stream.
|
||||
@param len yEncoded byte stream length.
|
||||
@param bin Output buffer.
|
||||
@param max Output buffer length.
|
||||
@return The number of bytes written to the output buffer.
|
||||
|
||||
@note If bin is NULL the function can be used to check the size
|
||||
of the decoded stream prior to allocating an output buffer.
|
||||
*/
|
||||
uint yDecode(const uchar *source, size_t len, uchar *bin = 0, size_t max = 0);
|
||||
};
|
||||
|
||||
|
||||
#endif // __NASCIIENC__
|
||||
50
include/framework/ascii/parser.h
Normal file
50
include/framework/ascii/parser.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __NASCII_PARSER__
|
||||
#define __NASCII_PARSER__
|
||||
|
||||
|
||||
/*!
|
||||
@short ASCII parsing tools.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
namespace GS {
|
||||
namespace AsciiParser {
|
||||
|
||||
/// Return true is the provided character is uppercase.
|
||||
bool IsUpperCase(const char s);
|
||||
/// Return whether a constant is float or int.
|
||||
bool IsConstantFloat(const char *s, const char *e);
|
||||
/// Find a character inside an ASCII block.
|
||||
const char *Find(const char *s, const char *e, char f);
|
||||
/// Run to end of string.
|
||||
const char *RunToEOS(const char *s, const char *e);
|
||||
/// Run to end of line marker.
|
||||
const char *RunToEOL(const char *s, const char *e);
|
||||
/// Skip end of line marker.
|
||||
const char *SkipEOL(const char *s, const char *e);
|
||||
/*!
|
||||
@short Run to the end of a group started with character 'op' closed with character 'cl'.
|
||||
@note This function automatically skips nested group of the same kind.
|
||||
*/
|
||||
const char *RunToEOG(const char *s, const char *e, char op, char cl);
|
||||
/// Run to the end of a C comment block (/*...*/).
|
||||
const char *RunToEOC(const char *s, const char *e);
|
||||
/// Run to the end of a C expression.
|
||||
const char *RunToEOE(const char *s, const char *e);
|
||||
/// Skip non-{space/tab/comments} string.
|
||||
const char *SkipEntry(const char *s, const char *e, bool skip_minus = false);
|
||||
/// Skip spaces.
|
||||
const char *SkipSpace(const char *s, const char *e);
|
||||
/// Go to the next entry.
|
||||
const char *NextEntry(const char *s, const char *e, bool skip_minus = false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // __NASCII_PARSER__
|
||||
47
include/framework/audio/audio_io.h
Normal file
47
include/framework/audio/audio_io.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __AUDIOIO__
|
||||
#define __AUDIOIO__
|
||||
|
||||
|
||||
#include "audio/stream_interface.h"
|
||||
#include "audio/stream_factory.h"
|
||||
#include "audio/sample_interface.h"
|
||||
#include "audio/sample_factory.h"
|
||||
#include "memory/singleton.h"
|
||||
#include "container/nlist.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*
|
||||
@short Audio factory.
|
||||
@author Emmanuel Julien (ejulien@owloh.com)
|
||||
*/
|
||||
class AudioIO : public Singleton <AudioIO>
|
||||
{
|
||||
AutoList <IAudioStreamFactory *> stream_factories;
|
||||
AutoList <ISampleFactory *> sample_factories;
|
||||
|
||||
public:
|
||||
|
||||
/// Register a stream codec.
|
||||
void RegisterStreamFactory(IAudioStreamFactory *);
|
||||
/// Register a sample codec.
|
||||
void RegisterSampleFactory(ISampleFactory *);
|
||||
|
||||
/// Open stream.
|
||||
IAudioStream *OpenStream(const char *path, const char *format = 0);
|
||||
/// Load a sample.
|
||||
ISample *LoadSample(const char *path, const char *format = 0);
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __AUDIOIO__
|
||||
|
||||
32
include/framework/audio/sample_factory.h
Normal file
32
include/framework/audio/sample_factory.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __ISAMPLEFACTORY__
|
||||
#define __ISAMPLEFACTORY__
|
||||
|
||||
|
||||
namespace GS {
|
||||
struct ISample;
|
||||
|
||||
/*
|
||||
@short Sample I/O codec interface.
|
||||
@author Emmanuel Julien (ejulien@owloh.com)
|
||||
*/
|
||||
struct ISampleFactory
|
||||
{
|
||||
/// Get the codec name.
|
||||
virtual const char *GetName() = 0;
|
||||
/// Load a sample.
|
||||
virtual ISample *Load(const char *path) = 0;
|
||||
|
||||
virtual ~ISampleFactory() {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __ISAMPLEFACTORY__
|
||||
|
||||
46
include/framework/audio/sample_format.h
Normal file
46
include/framework/audio/sample_format.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NSAMPLEFORMAT__
|
||||
#define __NSAMPLEFORMAT__
|
||||
|
||||
|
||||
#include "ntypes.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
@short Sample format.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
struct SampleFormat
|
||||
{
|
||||
enum Format
|
||||
{
|
||||
Format_PCM = 0,
|
||||
#if __PLATFORM_NINTENDO_WII__
|
||||
Format_Wii_ADPCM
|
||||
#endif
|
||||
};
|
||||
|
||||
Format format;
|
||||
uint channels;
|
||||
|
||||
uint frequency;
|
||||
uchar resolution;
|
||||
|
||||
/// Get the PCM data memory footprint a given number of samples in this format.
|
||||
uint GetPCMDataSize(uint sample_count) const
|
||||
{ return (sample_count * channels * resolution) / 8; }
|
||||
|
||||
SampleFormat(Format _format = Format_PCM, uint _channels = 2, uint _frequency = 48000, uchar _bit_per_sample = 16) : format(_format), channels(_channels), frequency(_frequency), resolution(_bit_per_sample) {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NSAMPLEFORMAT__
|
||||
37
include/framework/audio/sample_interface.h
Normal file
37
include/framework/audio/sample_interface.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __ISAMPLE__
|
||||
#define __ISAMPLE__
|
||||
|
||||
|
||||
#include "audio/sample_format.h"
|
||||
#include "time/ntime.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
@short Sample base interface.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
struct ISample
|
||||
{
|
||||
/// Return the format identifier (eg. "WAV").
|
||||
virtual const char *GetFormat() = 0;
|
||||
|
||||
/// Get sample format.
|
||||
virtual bool GetSampleFormat(SampleFormat &) const = 0;
|
||||
/// Get sample duration.
|
||||
virtual Time GetDuration() const = 0;
|
||||
|
||||
virtual ~ISample() {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __ISAMPLE__
|
||||
34
include/framework/audio/sample_stream_factory.h
Normal file
34
include/framework/audio/sample_stream_factory.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __SAMPLESTREAMFACTORY__
|
||||
#define __SAMPLESTREAMFACTORY__
|
||||
|
||||
|
||||
#include "audio/sample_interface.h"
|
||||
#include "audio/sample_factory.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
struct ISample;
|
||||
|
||||
/*!
|
||||
@short Sample stream factory
|
||||
This codec can decode any supported audio stream to a WAV sample.
|
||||
@author Emmanuel Julien (ejulien@owloh.com)
|
||||
*/
|
||||
struct SampleStreamFactory : public ISampleFactory
|
||||
{
|
||||
/// Get the codec name.
|
||||
virtual const char *GetName() { return "Stream"; }
|
||||
/// Load a sample.
|
||||
virtual ISample *Load(const char *path);
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __SAMPLESTREAMFACTORY__
|
||||
60
include/framework/audio/sample_wav.h
Normal file
60
include/framework/audio/sample_wav.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __SAMPLEWAV__
|
||||
#define __SAMPLEWAV__
|
||||
|
||||
|
||||
#include "audio/sample_interface.h"
|
||||
#include "time/ntime.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
@short WAV sample.
|
||||
@author Emmanuel Julien (ejulien@owloh.com)
|
||||
*/
|
||||
class SampleWav : public ISample
|
||||
{
|
||||
friend struct SampleWavFactory;
|
||||
|
||||
protected:
|
||||
|
||||
SampleFormat format;
|
||||
|
||||
uint sample_count;
|
||||
Array <char> pcm_data;
|
||||
|
||||
public:
|
||||
|
||||
/// Return the sample count.
|
||||
uint GetSampleCount() const { return sample_count; }
|
||||
/// Return the PCM data.
|
||||
void *GetPCMData() const { return pcm_data.c_ptr(); }
|
||||
/// Return the PCM data size.
|
||||
uint GetPCMDataSize() const;
|
||||
|
||||
/// Set PCM data, the data array content will be transfered to the sample.
|
||||
void Set(Array <char> &data, uint sample_count, const SampleFormat &);
|
||||
/// Allocate PCM samples for a given format.
|
||||
char *AllocAs(uint sample_count, const SampleFormat &);
|
||||
|
||||
/// Return the sample format identifier (eg. "WAV").
|
||||
virtual const char *GetFormat() { return "WAV"; }
|
||||
|
||||
/// Get the sample format.
|
||||
virtual bool GetSampleFormat(SampleFormat &) const;
|
||||
/// Get sample duration.
|
||||
virtual Time GetDuration() const;
|
||||
|
||||
SampleWav() : sample_count(0) {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __SAMPLEWAV__
|
||||
29
include/framework/audio/sample_wav_factory.h
Normal file
29
include/framework/audio/sample_wav_factory.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __SAMPLEWAVCODEC__
|
||||
#define __SAMPLEWAVCODEC__
|
||||
|
||||
|
||||
#include "audio/sample_factory.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
struct ISample;
|
||||
|
||||
/// Sample WAV codec
|
||||
struct SampleWavFactory : public ISampleFactory
|
||||
{
|
||||
/// Get the codec name.
|
||||
virtual const char *GetName() { return "WAV"; }
|
||||
/// Load a sample.
|
||||
virtual ISample *Load(const char *path);
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __SAMPLEWAVCODEC__
|
||||
31
include/framework/audio/stream_factory.h
Normal file
31
include/framework/audio/stream_factory.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __ISTREAMFACTORY__
|
||||
#define __ISTREAMFACTORY__
|
||||
|
||||
|
||||
namespace GS {
|
||||
struct IAudioStream;
|
||||
|
||||
/*
|
||||
@short Stream factory interface.
|
||||
@author Emmanuel Julien (ejulien@owloh.com)
|
||||
*/
|
||||
struct IAudioStreamFactory
|
||||
{
|
||||
/// Get factory name.
|
||||
virtual const char *GetName() = 0;
|
||||
/// Open a stream.
|
||||
virtual IAudioStream *Open(const char *path) = 0;
|
||||
|
||||
virtual ~IAudioStreamFactory() {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __ISTREAMFACTORY__
|
||||
42
include/framework/audio/stream_interface.h
Normal file
42
include/framework/audio/stream_interface.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __AUDIOSTREAMINTERFACE__
|
||||
#define __AUDIOSTREAMINTERFACE__
|
||||
|
||||
|
||||
#include "audio/sample_format.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*
|
||||
@short Audio stream interface.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
struct IAudioStream
|
||||
{
|
||||
SampleFormat format;
|
||||
|
||||
/// Return the stream data format (eg. "OGG").
|
||||
virtual const char *GetFormat() = 0;
|
||||
|
||||
virtual bool Seek(int t_ms = 0) = 0;
|
||||
virtual bool IsEOF() const = 0;
|
||||
|
||||
virtual size_t GetPCM(void *) = 0;
|
||||
virtual size_t GetPCMBufferSize() const = 0;
|
||||
|
||||
virtual bool Open(const char *uri) = 0;
|
||||
virtual void Close() = 0;
|
||||
|
||||
virtual ~IAudioStream() {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __AUDIOSTREAMINTERFACE__
|
||||
140
include/framework/bih/bih.h
Normal file
140
include/framework/bih/bih.h
Normal file
@ -0,0 +1,140 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NBIH__
|
||||
#define __NBIH__
|
||||
|
||||
|
||||
#include "geometry/bounding_box.h"
|
||||
#include "container/narray.h"
|
||||
#include "memory/nauto_ptr.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace BIH {
|
||||
|
||||
// Bounding interval hierarchy node.
|
||||
struct Node
|
||||
{
|
||||
char axis; ///< @TODO: Packed bitfield!
|
||||
void *p; ///< Pointer to child nodes or index array.
|
||||
|
||||
union
|
||||
{
|
||||
uint count; ///< Index count in leaf.
|
||||
float split[2]; ///< Split planes.
|
||||
};
|
||||
|
||||
Node() : axis(3), p(0) {}
|
||||
~Node();
|
||||
};
|
||||
|
||||
struct StackEntry
|
||||
{
|
||||
Node *node;
|
||||
float tmin, tmax;
|
||||
};
|
||||
|
||||
//
|
||||
struct Trace
|
||||
{
|
||||
StackEntry stack[65];
|
||||
uint stack_pos;
|
||||
|
||||
bool want_closest;
|
||||
|
||||
bool has_i; ///< Do we have an intersection.
|
||||
float i_t; ///< Distance to intersection from ray's origin.
|
||||
Vector4 s; ///< Ray origin.
|
||||
Vector4 d; ///< Ray direction.
|
||||
|
||||
uint node_visited; ///< Number of nodes visited.
|
||||
|
||||
Trace(bool closest = true) : want_closest(closest), has_i(false) {}
|
||||
};
|
||||
|
||||
/*!
|
||||
@short Bounding interval hierarchy.
|
||||
|
||||
This is a fully generic bounding interval hierarchy implementation.
|
||||
In order to use this structure on a custom set of data you need to derive
|
||||
from this class and provide the implementation for the TraceLeaf method.
|
||||
|
||||
In order to build the structure you simply provide a list of volumes to the
|
||||
build() methods.
|
||||
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
class Tree
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Minimum leaf volume count.
|
||||
uint min_leaf_vcount;
|
||||
|
||||
MinMax minmax; ///< Hierarchy bounding box.
|
||||
AutoPtr <Node> root; ///< Hierarchy root node.
|
||||
|
||||
Array <uint> sarray; ///< Index array.
|
||||
|
||||
uint node_count;
|
||||
uint leaf_count;
|
||||
uint depth;
|
||||
/*!
|
||||
@name Trace functions.
|
||||
@{
|
||||
*/
|
||||
/// Trace a leaf.
|
||||
virtual void TraceLeaf(Node *leaf, float tmin, float tmax, Trace &trace, void *parm = 0) = 0;
|
||||
/// Trace a node.
|
||||
void TraceNode(Node *node, float tmin, float tmax, Trace &trace);
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@name Intersection functions.
|
||||
@{
|
||||
*/
|
||||
/// Intersect a node.
|
||||
uint IntersectNode(Node *node, MinMax &sub_mm, uint *index_array, uint max_index);
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@name Build functions.
|
||||
@{
|
||||
*/
|
||||
/// Create a leaf.
|
||||
void MakeNodeLeaf(Node *node, uint count, uint *sarray, MinMax *varray);
|
||||
/// Perform a node split.
|
||||
void DoNodeSplit(MinMax &minmax, uint count, uint *sarray, MinMax *varray, uint &pivot, Node *node, uint &split_axis);
|
||||
/// Split an index list of volumes.
|
||||
bool Split(MinMax &minmax, uint count, uint *sarray, MinMax *varray, Node *node, uint depth);
|
||||
|
||||
/// Build hierarchy from a set of input volumes.
|
||||
virtual bool Build(uint volume_count, MinMax *varray);
|
||||
/// @}
|
||||
|
||||
public:
|
||||
|
||||
/// Intersect tree with an axis aligned bounding box.
|
||||
uint Intersect(MinMax &minmax, uint *index_array, uint max_index);
|
||||
/*
|
||||
@short Raytrace hierarchy.
|
||||
@note Ray direction must be normalized.
|
||||
*/
|
||||
virtual void Raytrace(Trace &trace, const Vector4 &s, const Vector4 &d, float l = -1.f, void *parm = 0);
|
||||
|
||||
/// Delete hierarchy.
|
||||
virtual void Free();
|
||||
|
||||
Tree();
|
||||
virtual ~Tree();
|
||||
};
|
||||
|
||||
} // BIH
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NBIH__
|
||||
106
include/framework/color/color.h
Normal file
106
include/framework/color/color.h
Normal file
@ -0,0 +1,106 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NCOLOR__
|
||||
#define __NCOLOR__
|
||||
|
||||
|
||||
#include "math/vector.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
@short The base color object.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct Color : public Vector4
|
||||
{
|
||||
bool operator == (const Vector4 &b) const { return Math::TestEqual(x, b.x) && Math::TestEqual(y, b.y) && Math::TestEqual(z, b.z) && Math::TestEqual(w, b.w); }
|
||||
bool operator != (const Vector4 &b) const { return !Math::TestEqual(x, b.x) || !Math::TestEqual(y, b.y) || !Math::TestEqual(z, b.z) || !Math::TestEqual(w, b.w); }
|
||||
|
||||
/// Standard C++ operators.
|
||||
void operator += (const Color &b) { x += b.x; y += b.y; z += b.z; w += b.w; };
|
||||
void operator += (const float k) { x += k; y += k; z += k; w += k; };
|
||||
void operator -= (const Color &b) { x -= b.x; y -= b.y; z -= b.z; w -= b.w; };
|
||||
void operator -= (const float k) { x -= k; y -= k; z -= k; w -= k; };
|
||||
void operator *= (const Color &b) { x *= b.x; y *= b.y; z *= b.z; w *= b.w; };
|
||||
void operator *= (const float k) { x *= k; y *= k; z *= k; w *= k; };
|
||||
void operator /= (const Color &b) { x /= b.x; y /= b.y; z /= b.z; w /= b.w; };
|
||||
void operator /= (const float k) { float k_ = 1.0f / k; x *= k_; y *= k_; z *= k_; w *= k_; };
|
||||
|
||||
Color operator + (const Color &b) const { return Color(x + b.x, y + b.y, z + b.z, w + b.w); }
|
||||
Color operator + (const float v) const { return Color(x + v, y + v, z + v, w + v); }
|
||||
Color operator - (const Color &b) const { return Color(x - b.x, y - b.y, z - b.z, w - b.w); }
|
||||
Color operator - (const float v) const { return Color(x - v, y - v, z - v, w - v); }
|
||||
Color operator * (const Color &b) const { return Color(x * b.x, y * b.y, z * b.z, w * b.w); }
|
||||
Color operator * (const float v) const { return Color(x * v, y * v, z * v, w * v); }
|
||||
Color operator / (const Color &b) const { return Color(x / b.x, y / b.y, z / b.z, w / b.w); }
|
||||
Color operator / (const float v) const { return Color(x / v, y / v, z / v, w / v); }
|
||||
|
||||
void operator = (const Vector4 &v) { x = v.x; y = v.y; z = v.z; w = v.w; }
|
||||
|
||||
/*!
|
||||
@short Return a grayscale value representing this color.
|
||||
|
||||
The grayscale value is computed accounting for the human eye color intensity perception.
|
||||
@see FastGray().
|
||||
*/
|
||||
inline float Grayscale() const
|
||||
{ return 0.3f * x + 0.59f * y + 0.11f * z; }
|
||||
/*!
|
||||
@short Return a grayscale value representing this color.
|
||||
|
||||
@note This function is not optically accurate.
|
||||
@see Grayscale().
|
||||
*/
|
||||
inline float Fastgray() const
|
||||
{ return (x + y + z) / 3.f; }
|
||||
|
||||
/// Return the color object as an RGBA value.
|
||||
uint AsInteger() const;
|
||||
/// Load the color object from an RGBA value.
|
||||
void FromInteger(uint value);
|
||||
|
||||
/*!
|
||||
@name Static color objects.
|
||||
@{
|
||||
*/
|
||||
static Color White;
|
||||
static Color Grey;
|
||||
static Color Black;
|
||||
static Color Red;
|
||||
static Color Green;
|
||||
static Color Blue;
|
||||
static Color Yellow;
|
||||
static Color Purple;
|
||||
/// @}
|
||||
|
||||
/// Scale color not alpha.
|
||||
Color ScaleChroma(float k) const
|
||||
{ return Color(x * k, y * k, z * k, w); }
|
||||
|
||||
/// Return a color object from a vector object.
|
||||
static Color FromVector(Vector4 &v)
|
||||
{ return Color(v.x, v.y, v.z, v.w); }
|
||||
|
||||
static uint ARGBtoRGBA(uint argb)
|
||||
{ return ((argb & 0xff) << 24) + (((argb >> 8) & 0xff) << 16) + (((argb >> 16) & 0xff) << 8) + ((argb >> 24) & 0xff); }
|
||||
|
||||
Color(const Vector4 &v)
|
||||
{ *this = v; }
|
||||
Color(uint rgba32)
|
||||
{ FromInteger(rgba32); }
|
||||
|
||||
Color(float r, float g, float b, float a = 1) : Vector4(r, g, b, a) {}
|
||||
Color() {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NCOLOR__
|
||||
|
||||
136
include/framework/data/nvariant.h
Normal file
136
include/framework/data/nvariant.h
Normal file
@ -0,0 +1,136 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NVARIANT__
|
||||
#define __NVARIANT__
|
||||
|
||||
|
||||
#include "nstring/nstring.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
@short Base property.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
class Variant
|
||||
{
|
||||
public:
|
||||
|
||||
enum Type
|
||||
{
|
||||
VariantNone = 0,
|
||||
VariantFloat,
|
||||
VariantBool,
|
||||
VariantInteger,
|
||||
VariantString,
|
||||
VariantBinary
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
void Reset();
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
@name Property value.
|
||||
@{
|
||||
*/
|
||||
Type type;
|
||||
|
||||
union
|
||||
{
|
||||
char *d_value;
|
||||
bool b_value;
|
||||
float f_value;
|
||||
int i_value;
|
||||
uint u_value;
|
||||
};
|
||||
|
||||
size_t d_size; /// Binary data size.
|
||||
String s_value;
|
||||
/// @}
|
||||
|
||||
String id; ///< Variant id.
|
||||
|
||||
bool operator < (const Variant &b) const;
|
||||
bool operator > (const Variant &b) const;
|
||||
bool operator == (const Variant &b) const;
|
||||
bool operator != (const Variant &b) const;
|
||||
|
||||
Variant &operator = (bool v);
|
||||
Variant &operator = (int v);
|
||||
Variant &operator = (uint v);
|
||||
Variant &operator = (const char *v);
|
||||
Variant &operator = (float v);
|
||||
|
||||
Variant &operator = (const Variant &v);
|
||||
|
||||
/// Get property type.
|
||||
Type GetType() const { return type; }
|
||||
/// Free current property value.
|
||||
void Free();
|
||||
|
||||
/// Get string value.
|
||||
bool Get(const char * &v) const;
|
||||
/// Get bool value.
|
||||
bool Get(bool &v) const;
|
||||
/// Get integer value.
|
||||
bool Get(int &v) const;
|
||||
/// Get unsigned value.
|
||||
bool Get(uint &v) const;
|
||||
/// Get float value.
|
||||
bool Get(float &v) const;
|
||||
|
||||
/// Set binary data.
|
||||
bool SetBinary(const void *data, size_t size);
|
||||
/// Get binary data.
|
||||
bool GetBinary(void *&data, size_t &size) const;
|
||||
|
||||
/// Direct access to the binary buffer.
|
||||
void *GetBinaryBuffer() const { return GetType() == VariantBinary ? (void *)d_value : 0; }
|
||||
/// Binary buffer size.
|
||||
size_t GetBinarySize() const { return GetType() == VariantBinary ? d_size : 0; }
|
||||
|
||||
/// Get children array.
|
||||
bool Get(List <Variant *> &a);
|
||||
|
||||
Variant(const char *v)
|
||||
{ Reset(); *this = v; }
|
||||
Variant(bool v)
|
||||
{ Reset(); *this = v; }
|
||||
Variant(int v)
|
||||
{ Reset(); *this = v; }
|
||||
Variant(uint v)
|
||||
{ Reset(); *this = v; }
|
||||
Variant(float v)
|
||||
{ Reset(); *this = v; }
|
||||
Variant(void *d, size_t l)
|
||||
{ Reset(); SetBinary(d, l); }
|
||||
|
||||
Variant(const char *i, const char *v)
|
||||
{ Reset(); id = i; *this = v; }
|
||||
Variant(const char *i, bool v)
|
||||
{ Reset(); id = i; *this = v; }
|
||||
Variant(const char *i, int v)
|
||||
{ Reset(); id = i; *this = v; }
|
||||
Variant(const char *i, uint v)
|
||||
{ Reset(); id = i; *this = v; }
|
||||
Variant(const char *i, float v)
|
||||
{ Reset(); id = i; *this = v; }
|
||||
|
||||
Variant()
|
||||
{ Reset(); }
|
||||
~Variant();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // __NVARIANT__
|
||||
|
||||
65
include/framework/data/registry.h
Normal file
65
include/framework/data/registry.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NREGISTRY__
|
||||
#define __NREGISTRY__
|
||||
|
||||
|
||||
#include "metafile/nml.h"
|
||||
#include "messaging/messaging.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
enum RegistryMessage
|
||||
{
|
||||
RegistryMsg_None = 0, ///< No message.
|
||||
RegistryMsg_StartKeyChangeBatch,
|
||||
RegistryMsg_KeyChange,
|
||||
RegistryMsg_EndKeyChangeBatch
|
||||
};
|
||||
|
||||
enum RegistryRValue
|
||||
{
|
||||
RegistryReturn_Ok = 0
|
||||
};
|
||||
|
||||
//
|
||||
struct RegistryKeyChange
|
||||
{
|
||||
String key;
|
||||
RegistryKeyChange(const char *k) { key = String(k).TrimChar(';'); }
|
||||
};
|
||||
|
||||
struct Registry;
|
||||
|
||||
/// Registry listener.
|
||||
struct RegistryListener
|
||||
{
|
||||
virtual RegistryRValue ProcessMessage(RegistryMessage message, const Registry *from, const void *parm) = 0;
|
||||
virtual ~RegistryListener() {}
|
||||
};
|
||||
|
||||
/*
|
||||
@short Registry.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct Registry : public Messaging::Broadcaster <RegistryMessage, RegistryListener, Registry *>, public NML::File
|
||||
{
|
||||
NML::Tag *CreateKey(const char *path, const Variant *value = 0, bool recursive = true);
|
||||
NML::Tag *CreateKey(const char *path, const Variant &value, bool recursive = true);
|
||||
bool DeleteKey(const char *path);
|
||||
|
||||
/// Get the float value of a given key.
|
||||
float GetReal(const char *path, float default_value = 0) const;
|
||||
/// Get the boolean value of a given key.
|
||||
bool GetBool(const char *path, bool default_value = false) const;
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NREGISTRY__
|
||||
56
include/framework/font/font_cache.h
Normal file
56
include/framework/font/font_cache.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __FONTCACHE__
|
||||
#define __FONTCACHE__
|
||||
|
||||
|
||||
#include "font/font_factory.h"
|
||||
#include "font/font_extended.h"
|
||||
#include "memory/nauto_ptr.h"
|
||||
#include "memory/nweak_ptr.h"
|
||||
#include "container/nlist.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/// Extended font alias.
|
||||
struct FontAlias
|
||||
{
|
||||
String alias;
|
||||
sFontEx font;
|
||||
};
|
||||
|
||||
/*
|
||||
@short Font cache.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
class FontCache : public SharedObject
|
||||
{
|
||||
AutoList <FontAlias *> font_aliases;
|
||||
AutoPtr <IFontFactory> font_factory;
|
||||
|
||||
public:
|
||||
|
||||
FontEx *GetFont(const char *) const;
|
||||
FontAlias *GetAlias(const char *) const;
|
||||
FontEx *GetAliasedFont(const char *) const;
|
||||
|
||||
FontEx *LoadFont(const char *, const char *alias = 0);
|
||||
|
||||
void DeleteAlias(const char *);
|
||||
void DeleteAllFont();
|
||||
|
||||
FontCache(IFontFactory *factory) : font_factory(factory) {}
|
||||
~FontCache();
|
||||
};
|
||||
|
||||
typedef SharedPtr <FontCache> sFontCache;
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __FONTCACHE__
|
||||
70
include/framework/font/font_extended.h
Normal file
70
include/framework/font/font_extended.h
Normal file
@ -0,0 +1,70 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __FONTEXTENDED__
|
||||
#define __FONTEXTENDED__
|
||||
|
||||
|
||||
#include "font/font_interface.h"
|
||||
#include "memory/nauto_ptr.h"
|
||||
#include "memory/nweak_ptr.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
@short Extended font to help normalization.
|
||||
@author Emmanuel Julien (ejulien@owloh.com)
|
||||
*/
|
||||
class FontEx : public IFont
|
||||
{
|
||||
sIFont font;
|
||||
WeakPtr <IFont> current_glyph_font;
|
||||
|
||||
int pixel_size;
|
||||
|
||||
public:
|
||||
|
||||
WeakPtr <IFont> fallback; ///< Fall-back font when a glyph is not found in the current font.
|
||||
|
||||
float size_multiplier, ///< Offsets to ease TTF normalization.
|
||||
tracking_offset,
|
||||
leading_offset;
|
||||
|
||||
/// Return the font name.
|
||||
const char *GetName() const { return font->GetName(); }
|
||||
/// Return the bounding rect for a given string.
|
||||
iRect GetTextBoundRect(const char *text) const { return font->GetTextBoundRect(text); }
|
||||
|
||||
/// Set font size in pixels.
|
||||
bool SetPixelSize(int);
|
||||
/// Get font height in pixels.
|
||||
int GetHeight() const;
|
||||
/// Get font current glyph advance.
|
||||
int GetAdvance() const;
|
||||
|
||||
/// Return true if the font supports kerning.
|
||||
bool HasKerning() const;
|
||||
/// Return the kerning for a glyph pair.
|
||||
int GetKerning(uint previous_glyph, uint glyph) const;
|
||||
|
||||
/// Load the glyph corresponding to a UTF-32 codepoint.
|
||||
bool LoadGlyph(uint codepoint, bool for_render);
|
||||
/// Render currently loaded glyph to a picture.
|
||||
bool RenderCurrentGlyph(Picture &picture, const iPoint &position, const iRect &clip, const Color &color);
|
||||
|
||||
/// Set a fallback font to query in case a glyph cannot be found in this font.
|
||||
void SetFallback(IFont *f) { fallback = f; }
|
||||
|
||||
FontEx(IFont *f) : font(f), size_multiplier(1), tracking_offset(1), leading_offset(1) {}
|
||||
};
|
||||
|
||||
typedef SharedPtr <FontEx> sFontEx;
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __FONTEXTENDED__
|
||||
26
include/framework/font/font_factory.h
Normal file
26
include/framework/font/font_factory.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __FONTFACTORY__
|
||||
#define __FONTFACTORY__
|
||||
|
||||
|
||||
namespace GS {
|
||||
struct IFont;
|
||||
|
||||
/// Font factory.
|
||||
struct IFontFactory
|
||||
{
|
||||
/// Load a font.
|
||||
virtual IFont *LoadFont(const char *) = 0;
|
||||
|
||||
virtual ~IFontFactory() {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __FONTFACTORY__
|
||||
60
include/framework/font/font_interface.h
Normal file
60
include/framework/font/font_interface.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __FONTINTERFACE__
|
||||
#define __FONTINTERFACE__
|
||||
|
||||
|
||||
#include "color/color.h"
|
||||
#include "geometry/rect.h"
|
||||
#include "memory/nshared_ptr.h"
|
||||
#include "nstring/nstring.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
class Picture;
|
||||
|
||||
/*!
|
||||
@short Font interface.
|
||||
@author Emmanuel Julien (ejulien@owloh.com)
|
||||
*/
|
||||
struct IFont : public SharedObject
|
||||
{
|
||||
/// Return the font name.
|
||||
virtual const char *GetName() const = 0;
|
||||
|
||||
/// Return the bounding rect for a given string.
|
||||
virtual iRect GetTextBoundRect(const char *) const = 0;
|
||||
|
||||
/// Set font size in pixels.
|
||||
virtual bool SetPixelSize(int) = 0;
|
||||
/// Get font height in pixels.
|
||||
virtual int GetHeight() const = 0;
|
||||
/// Get font current glyph advance.
|
||||
virtual int GetAdvance() const = 0;
|
||||
|
||||
/// Return true if the font supports kerning.
|
||||
virtual bool HasKerning() const = 0;
|
||||
/// Return the kerning for a glyph codepoint.
|
||||
virtual int GetKerning(uint previous_codepoint, uint codepoint) const = 0;
|
||||
|
||||
/// Load the glyph corresponding to a UTF-32 codepoint.
|
||||
virtual bool LoadGlyph(uint codepoint, bool for_render) = 0;
|
||||
/// Render currently loaded glyph to a picture.
|
||||
virtual bool RenderCurrentGlyph(Picture &picture, const iPoint &position, const iRect &clip, const Color &color = Color::White) = 0;
|
||||
|
||||
/// Set a fallback font to query in case a glyph cannot be found in this font.
|
||||
virtual void SetFallback(IFont *) {}
|
||||
|
||||
virtual ~IFont() {}
|
||||
};
|
||||
|
||||
typedef SharedPtr <IFont> sIFont;
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __FONTINTERFACE__
|
||||
122
include/framework/font/font_renderer.h
Normal file
122
include/framework/font/font_renderer.h
Normal file
@ -0,0 +1,122 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __FONTRENDERER__
|
||||
#define __FONTRENDERER__
|
||||
|
||||
|
||||
#include "font/font_extended.h"
|
||||
#include "font/font_cache.h"
|
||||
#include "math/vector.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
class Picture;
|
||||
struct SubString;
|
||||
|
||||
/// Text widget state structure.
|
||||
class TextState
|
||||
{
|
||||
int size;
|
||||
float tracking, ///< Text tracking (horizontal offset between two characters).
|
||||
leading; ///< Text heading (vertical offset between lines).
|
||||
|
||||
public:
|
||||
|
||||
enum Format
|
||||
{
|
||||
Line = 0,
|
||||
Paragraph,
|
||||
Column
|
||||
};
|
||||
|
||||
enum Alignment
|
||||
{
|
||||
Left = 0,
|
||||
Right,
|
||||
Center,
|
||||
Justify
|
||||
};
|
||||
|
||||
sFontEx font;
|
||||
Color color;
|
||||
|
||||
Format format; ///< Text format.
|
||||
Alignment alignment; ///< Text alignment.
|
||||
int column_width; ///< Text column width.
|
||||
|
||||
int GetSize() const { return font.IsValid() ? (int)(size * font->size_multiplier) : size; }
|
||||
float GetTracking() const { return font.IsValid() ? tracking + font->tracking_offset : tracking; }
|
||||
float GetLeading() const { return font.IsValid() ? leading + font->leading_offset : leading; }
|
||||
|
||||
void SetSize(int s) { size = s; }
|
||||
void SetTracking(float t) { tracking = t; }
|
||||
void SetLeading(float l) { leading = l; }
|
||||
|
||||
TextState()
|
||||
{
|
||||
size = 16;
|
||||
color = Color::Black;
|
||||
|
||||
format = Line;
|
||||
alignment = Left;
|
||||
|
||||
column_width = 80;
|
||||
tracking = 0;
|
||||
leading = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@short Font renderer.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
class FontRenderer
|
||||
{
|
||||
public:
|
||||
|
||||
enum CommandCode
|
||||
{
|
||||
CommandNone = 0,
|
||||
CommandColor,
|
||||
CommandFont,
|
||||
CommandSize,
|
||||
|
||||
CommandParseError
|
||||
};
|
||||
|
||||
static float default_text_tracking;
|
||||
static float default_text_heading;
|
||||
|
||||
/// Renderer command.
|
||||
struct Command
|
||||
{
|
||||
CommandCode code;
|
||||
Vector4 vector;
|
||||
sIFont font;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
/// Check current string for a command.
|
||||
static const char *CheckCommand(const char *string, Command &command);
|
||||
/// Get the next sub-string from the current text buffer.
|
||||
static const char *FetchSubString(const char *string, SubString &sstr, TextState &state, int max_width, int max_character);
|
||||
/// Draw a substring to a picture.
|
||||
static void DrawSubString(SubString &sub_string, Picture &output, TextState &state, const iRect &out_rect, const iRect &clip_rect, int justification);
|
||||
|
||||
public:
|
||||
|
||||
/// Format a string using a text state, return the required output rectangle.
|
||||
static iRect Format(const char *text, const TextState &in_state, const iRect &out_rect);
|
||||
/// Compose a string using a text state.
|
||||
static iRect Compose(Picture &output, const char *text, const TextState &state, const iRect &out_rect, const iRect &clip_rect);
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __FONTRENDERER__
|
||||
184
include/framework/geometry/bounding_box.h
Normal file
184
include/framework/geometry/bounding_box.h
Normal file
@ -0,0 +1,184 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __NBOUNDINGBOX__
|
||||
#define __NBOUNDINGBOX__
|
||||
|
||||
|
||||
#include "math/matrix3.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
@short AABB.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
class MinMax
|
||||
{
|
||||
protected:
|
||||
|
||||
enum
|
||||
{
|
||||
ClipNone = 0,
|
||||
ClipRight = 1,
|
||||
ClipLeft = 2,
|
||||
ClipTop = 4,
|
||||
ClipBottom = 8,
|
||||
ClipFront = 16,
|
||||
ClipBack = 32
|
||||
};
|
||||
|
||||
/// Internal use.
|
||||
uint cc_oc(const Vector4 &min, const Vector4 &max, const Vector4 &p) const
|
||||
{
|
||||
uint oc = ClipNone;
|
||||
if (p.x > max.x) oc |= ClipRight;
|
||||
else if (p.x < min.x) oc |= ClipLeft;
|
||||
if (p.y > max.y) oc |= ClipTop;
|
||||
else if (p.y < min.y) oc |= ClipBottom;
|
||||
if (p.z > max.z) oc |= ClipBack;
|
||||
else if (p.z < min.z) oc |= ClipFront;
|
||||
return oc;
|
||||
}
|
||||
|
||||
/// Internal use.
|
||||
uint ss_oc(const Vector4 &p) const
|
||||
{
|
||||
uint oc = ClipNone;
|
||||
oc |= p.x > 0 ? ClipRight : ClipLeft;
|
||||
oc |= p.y > 0 ? ClipTop : ClipBottom;
|
||||
oc |= p.z > 0 ? ClipBack : ClipFront;
|
||||
return oc;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Vector4 mn, mx;
|
||||
|
||||
/// Return the start of the interval on a given axis.
|
||||
float GetMin(uint axis) const
|
||||
{ return mn[axis]; }
|
||||
/// Return the end of the interval on a given axis.
|
||||
float GetMax(uint axis) const
|
||||
{ return mx[axis]; }
|
||||
/// Return whether the MinMax object overlap with another one.
|
||||
bool TestAxisOverlap(const MinMax &b, uint axis) const
|
||||
{ return (b.mn[axis] > mx[axis]) || (b.mx[axis] < mn[axis]) ? false : true; }
|
||||
|
||||
/// Intersect ray with this minmax.
|
||||
bool IntersectRay(const Vector4 &o, const Vector4 &d, float &tmin, float &tmax);
|
||||
|
||||
/// Returns whether a line intersect with the MinMax.
|
||||
bool ClassifyLine(const Vector4 &p, const Vector4 &d, Vector4 &i, Vector4 *n = 0) const;
|
||||
/// Returns whether a segment intersect with the MinMax.
|
||||
bool ClassifySegment(const Vector4 &p0, const Vector4 &p1, Vector4 &i, Vector4 *n = 0) const;
|
||||
|
||||
/// Return whether two MinMax overlap at a given time.
|
||||
bool TestOverlap(const MinMax &b) const
|
||||
{
|
||||
if (mx.x < b.mn.x) return false;
|
||||
if (mx.y < b.mn.y) return false;
|
||||
if (mx.z < b.mn.z) return false;
|
||||
if (b.mx.x < mn.x) return false;
|
||||
if (b.mx.y < mn.y) return false;
|
||||
if (b.mx.z < mn.z) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Test position.
|
||||
inline bool IsInside(const Vector4 &p) const
|
||||
{ return (p.x < mn.x) || (p.y < mn.y) || (p.z < mn.z) || (p.x > mx.x) || (p.y > mx.y) || (p.z > mx.z) ? false : true; }
|
||||
|
||||
/// Grow the min~max boundaries to include another min~max structure.
|
||||
void Grow(const MinMax &b)
|
||||
{
|
||||
mn = Vector4::Minimum(b.mn, mn);
|
||||
mx = Vector4::Maximum(b.mx, mx);
|
||||
}
|
||||
|
||||
/// Grow the min~max boundaries to include a vector.
|
||||
void Grow(const Vector4 &p)
|
||||
{
|
||||
mn = Vector4::Minimum(p, mn);
|
||||
mx = Vector4::Maximum(p, mx);
|
||||
}
|
||||
|
||||
/// Get the min-max area.
|
||||
float GetArea() const
|
||||
{ return (mx.x - mn.x) * (mx.y - mn.y) * (mx.z - mn.z); }
|
||||
/// Get the min-max center.
|
||||
Vector4 GetCenter() const
|
||||
{ return (mn + mx) * 0.5f; }
|
||||
|
||||
/// Set min-max.
|
||||
void Set(const Vector4 &min, const Vector4 &max)
|
||||
{ mn = min; mx = max; }
|
||||
/// Set from position and size.
|
||||
void SetFromPositionSize(const Vector4 &p, const Vector4 &s)
|
||||
{
|
||||
mn = p - s * 0.5f;
|
||||
mx = p + s * 0.5f;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{ mn.Set(); mx.Set(); }
|
||||
|
||||
/*!
|
||||
@name Serialization
|
||||
@{
|
||||
*/
|
||||
bool FromMetaTag(NML::Tag &tag);
|
||||
NML::Tag *AsMetaTag();
|
||||
/// @}
|
||||
|
||||
MinMax() : mn(0, 0, 0), mx(0, 0, 0) {}
|
||||
MinMax(const Vector4 &min, const Vector4 &max) : mn(min), mx(max) {}
|
||||
};
|
||||
|
||||
/*!
|
||||
@short Oriented bounding box.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
struct OBB
|
||||
{
|
||||
Vector4 bb_position;
|
||||
Vector4 bb_scale;
|
||||
Matrix3 bb_rotation;
|
||||
|
||||
/// Compute the min/max of the OBB.
|
||||
void ComputeMinMax(MinMax &minmax);
|
||||
|
||||
/*!
|
||||
@short Transform OBB.
|
||||
@warning Scaling is not supported.
|
||||
*/
|
||||
void Transform(const Matrix4 &mtx);
|
||||
|
||||
/// OBB from min~max.
|
||||
static OBB FromMinMax(const MinMax &minmax)
|
||||
{ return OBB((minmax.mn + minmax.mx) * 0.5f, minmax.mx - minmax.mn); }
|
||||
|
||||
bool FromMetaTag(NML::Tag &tag);
|
||||
NML::Tag *AsMetaTag();
|
||||
|
||||
OBB(const MinMax &minmax)
|
||||
{ *this = FromMinMax(minmax); }
|
||||
OBB(const Vector4 &p, const Vector4 &s, const Matrix3 *m = 0)
|
||||
{
|
||||
bb_position = p;
|
||||
bb_scale = s;
|
||||
if (m)
|
||||
bb_rotation = *m;
|
||||
}
|
||||
OBB() {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NBOUNDINGBOX__
|
||||
|
||||
171
include/framework/geometry/curve.h
Normal file
171
include/framework/geometry/curve.h
Normal file
@ -0,0 +1,171 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NCURVE__
|
||||
#define __NCURVE__
|
||||
|
||||
|
||||
#include "math/nmath.h"
|
||||
#include "metafile/nml.h"
|
||||
#include "reflection/nenum_string.h"
|
||||
#include "container/narray_list.h"
|
||||
#include "time/ntime_range.h"
|
||||
#include "time/ntime.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
static const float DefaultCurveOptimizationThreshold = 0.05f;
|
||||
|
||||
/*
|
||||
@short Curve control point.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
struct CurvePoint
|
||||
{
|
||||
NPLACEMENT_NEW(Curve)
|
||||
|
||||
/// Curve control point shape.
|
||||
enum Shape
|
||||
{
|
||||
Shape_None = 0,
|
||||
Shape_Linear,
|
||||
Shape_TCB,
|
||||
Shape_Hermite,
|
||||
Shape_Bezier,
|
||||
Shape_Bezier2,
|
||||
Shape_Step
|
||||
};
|
||||
|
||||
Shape shape;
|
||||
|
||||
Time t;
|
||||
float v,
|
||||
tension, continuity, bias,
|
||||
param[4]; //< TCB parameters.
|
||||
|
||||
CurvePoint(const Time &time, float value, Shape shp = Shape_Linear) : t(time), v(value), shape(shp)
|
||||
{
|
||||
tension = 0;
|
||||
continuity = 0;
|
||||
bias = 0;
|
||||
|
||||
param[0] = param[1] = param[2] = param[3] = 0;
|
||||
}
|
||||
CurvePoint() : t(0), v(0), shape(Shape_Linear)
|
||||
{
|
||||
tension = 0;
|
||||
continuity = 0;
|
||||
bias = 0;
|
||||
|
||||
param[0] = param[1] = param[2] = param[3] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
@short Curve object.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
class Curve
|
||||
{
|
||||
public:
|
||||
|
||||
NPLACEMENT_NEW(Curve)
|
||||
|
||||
enum LoopMode
|
||||
{
|
||||
Reset = 0, ///< Returns 0.
|
||||
Constant, ///< Returns first/last knot value.
|
||||
Repeat, ///< Warp evaluation time to a value inside curve range and evaluate.
|
||||
Oscillate, ///< Ping-pong style evaluation.
|
||||
OffsetAndRepeat ///< Same as repeat but the whole curve is offset with the last knot value.
|
||||
};
|
||||
|
||||
static Reflection::Enum::Dict loop_mode_dict[];
|
||||
|
||||
protected:
|
||||
|
||||
ArrayList <CurvePoint *> points; ///< Curve knots.
|
||||
|
||||
uint Optimize(uint point_count, const CurvePoint *src, CurvePoint *dst, float threshold);
|
||||
|
||||
public:
|
||||
|
||||
/// Evaluate curve at a given time.
|
||||
void Evaluate(Time t, float *value, LoopMode loop_mode = Constant, Time loop_start = Time::Inf, Time loop_end = Time::Inf) const;
|
||||
|
||||
/// Evaluate incoming tangent to the curve.
|
||||
float Incoming(const CurvePoint *kf0, const CurvePoint *kf1, const CurvePoint *kf2) const;
|
||||
/// Evaluate outgoing tangent to the curve.
|
||||
float Outgoing(const CurvePoint *kf0, const CurvePoint *kf1, const CurvePoint *kfp) const;
|
||||
|
||||
/*!
|
||||
@short Update a control point.
|
||||
@note The time epsilon is considered on both side of the control
|
||||
points time. If no point to update is found a new point is
|
||||
inserted.
|
||||
*/
|
||||
void Update(const CurvePoint &, const Time &t_epsilon);
|
||||
/// Insert a control point.
|
||||
void Insert(const CurvePoint &);
|
||||
/// Append a control point to the control point list.
|
||||
void Append(const CurvePoint &);
|
||||
|
||||
/// Delete a curve control point from the channel.
|
||||
void Delete(CurvePoint *);
|
||||
|
||||
/// Get curve time range, very fast.
|
||||
TimeRange GetTimeRange() const;
|
||||
/// Get curve value range, requires a full parsing of the knot list.
|
||||
Range <float> GetValueRange() const;
|
||||
|
||||
/// Get curve range length in time.
|
||||
Time GetDuration() const { return GetTimeRange().valueRange(); }
|
||||
|
||||
/// Optimize curve removing the less influential knots.
|
||||
uint Optimize(float threshold = DefaultCurveOptimizationThreshold);
|
||||
|
||||
/// Return the curve control points as an array.
|
||||
ArrayList <CurvePoint *> &GetPoints() { return points; }
|
||||
/// Return the number of control point in curve.
|
||||
uint GetPointCount() const { return points.GetCount(); }
|
||||
|
||||
/// Sort curve point array by time.
|
||||
void Sort();
|
||||
/*!
|
||||
@short Set a control point content.
|
||||
|
||||
@Note This function does modify the internal ordering of the curve
|
||||
keys in order to keep them time ordered.
|
||||
Please use the Sort() function to make sure the curve can
|
||||
still be correctly evaluated after a key time modification.
|
||||
*/
|
||||
void SetPoint(uint index, const CurvePoint &content) const;
|
||||
|
||||
/// Allocate a set of control points.
|
||||
bool AllocatePoint(uint n);
|
||||
|
||||
/*!
|
||||
@short Return the closest point on curve to a given time position.
|
||||
The default behavior is to return the first point whose time is
|
||||
greater than the query time.
|
||||
*/
|
||||
int GetPointIndex(const Time &time, bool t_greater_than = true) const;
|
||||
|
||||
void Clear();
|
||||
|
||||
virtual size_t MemoryFootPrint() const { return size_t(points.GetCount()) * sizeof(CurvePoint) + sizeof(Curve); }
|
||||
|
||||
bool FromMetaTag(NML::Tag &);
|
||||
NML::Tag *AsMetaTag() const;
|
||||
|
||||
virtual ~Curve();
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NCURVE__
|
||||
76
include/framework/geometry/frustum.h
Normal file
76
include/framework/geometry/frustum.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NFRUSTRUM__
|
||||
#define __NFRUSTRUM__
|
||||
|
||||
|
||||
#include "geometry/plane.h"
|
||||
|
||||
|
||||
class nMatrix4;
|
||||
|
||||
namespace GS {
|
||||
|
||||
struct Shape;
|
||||
class MinMax;
|
||||
|
||||
/*!
|
||||
@short Frustum.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
class Frustum
|
||||
{
|
||||
public:
|
||||
|
||||
enum Visibility
|
||||
{
|
||||
Outside = 0,
|
||||
Inside,
|
||||
Clipped
|
||||
};
|
||||
|
||||
enum VolumePlane
|
||||
{
|
||||
Top = 0,
|
||||
Bottom,
|
||||
Left,
|
||||
Right,
|
||||
Near,
|
||||
Far
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
Vector4 vtx[8]; ///< Frustum vertices.
|
||||
Plane plane[6]; ///< Frustum planes.
|
||||
|
||||
public:
|
||||
|
||||
inline const Vector4 *GetVertices() const { return vtx; }
|
||||
|
||||
/// Compute perspective frustum volume planes.
|
||||
void SetPerspective(float fov, float near, float far, const Matrix4 *m = 0, float h_ar = 1, float v_ar = 1);
|
||||
/// Compute orthographic frustum volume planes.
|
||||
void SetOrthographic(float width, float height, float near, float far, const Matrix4 *m = 0, float h_ar = 1, float v_ar = 1);
|
||||
|
||||
/// Return the visibility flag of a vector set against this frustum.
|
||||
Visibility ClassifySet(uint count, const Vector4 * const GSRESTRICT set, const float offset = 0) const;
|
||||
/// Return the visibility flag of a frustum against this frustum.
|
||||
Visibility ClassifyFrustrum(const Frustum &frustum) const;
|
||||
/// Return the visibility flag of a sphere against this frustum.
|
||||
Visibility ClassifySphere(const Vector4 &p, float r) const;
|
||||
/// Return the visibility flag of a minmax against this frustum.
|
||||
Visibility ClassifyMinMax(const MinMax &mm, const Matrix4 *m = 0) const;
|
||||
|
||||
/// Return the visibility flag of a shape against this frustum.
|
||||
Visibility ClassifyShape(const Shape &s, const Matrix4 *m = 0) const;
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NFRUSTRUM__
|
||||
103
include/framework/geometry/geometric_tools.h
Normal file
103
include/framework/geometry/geometric_tools.h
Normal file
@ -0,0 +1,103 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NGEOMETRICTOOLS__
|
||||
#define __NGEOMETRICTOOLS__
|
||||
|
||||
|
||||
#include "math/vector.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace Geometric {
|
||||
|
||||
/// Compute 2d triangle area.
|
||||
float TriArea2D(float x0, float y0, float x1, float y1, float x2, float y2);
|
||||
|
||||
/*!
|
||||
@short Test intersection between a ray and a plane.
|
||||
|
||||
@param a Origin of the ray.
|
||||
@param v Direction of the ray.
|
||||
@param n Normal of the plane.
|
||||
@param p A point on the plane.
|
||||
|
||||
@param t Output, the parametric 't' value of the point of
|
||||
intersection.
|
||||
|
||||
@return False if the ray is embedded in or coplanar to the plane.
|
||||
True otherwise.
|
||||
*/
|
||||
bool LineIntersectPlane(const Vector4 &a, const Vector4 &v, const Vector4 &n, const Vector4 &p, float &t);
|
||||
|
||||
/*!
|
||||
@short Compute barycentric coordinates.
|
||||
*/
|
||||
void Barycentric(const Vector4 &a, const Vector4 &b, const Vector4 &c, const Vector4 &p, float &u, float &v, float &w);
|
||||
|
||||
/*!
|
||||
@short Test intersection between a ray and a plane.
|
||||
|
||||
@param a Origin of the ray.
|
||||
@param v Normalized direction of the ray.
|
||||
@param c Center of the sphere.
|
||||
@param r Radius of the sphere.
|
||||
|
||||
@param t Output, the parametric 't' value of the points of
|
||||
intersection. t[0] is the closest point of
|
||||
intersection to the origin of the ray.
|
||||
|
||||
@return False if no intersection.
|
||||
*/
|
||||
bool LineIntersectSphere(const Vector4 &a, const Vector4 &v, const Vector4 &c, float r, float t[2]);
|
||||
|
||||
/*!
|
||||
@short Determine the closest points between two lines.
|
||||
|
||||
@param a First point on first line.
|
||||
@param b Second point on first line.
|
||||
@param u First point on second line.
|
||||
@param v Second point on second line.
|
||||
|
||||
@param t Output, the parametric 't' values of the closest
|
||||
points on each line. t[0] belongs to (a;b), t[1]
|
||||
belongs to (u;v).
|
||||
|
||||
@return False if both lines are parallel.
|
||||
*/
|
||||
bool LineClosestPointToLine(const Vector4 &a, const Vector4 &b, const Vector4 &u, const Vector4 &v, float t[2]);
|
||||
|
||||
|
||||
/*!
|
||||
@short Determine the closest point to a line from a position in space.
|
||||
|
||||
@param a First point on line.
|
||||
@param b Second point on line.
|
||||
@param u Location.
|
||||
@param i Output the closest point on line to u.
|
||||
|
||||
@return t Parametric position of i on the [a;b] segment.
|
||||
If t < 0 or t > 1 then i lies outside the [a;b] segment.
|
||||
*/
|
||||
float LineClosestPoint(const Vector4 &a, const Vector4 &b, const Vector4 &u, Vector4 *p = 0);
|
||||
|
||||
/*!
|
||||
@short Determine the closest point to a segment from a position in space.
|
||||
|
||||
@param a First point on segment.
|
||||
@param b Second point on segment.
|
||||
@param u Location.
|
||||
@param i Output the closest point on segment to u.
|
||||
|
||||
@return t Parametric position of i on the [a;b] segment.
|
||||
*/
|
||||
float SegmentClosestPoint(const Vector4 &a, const Vector4 &b, const Vector4 &u, Vector4 *p = 0);
|
||||
|
||||
} // Geometric
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NGEOMETRICTOOLS__
|
||||
55
include/framework/geometry/plane.h
Normal file
55
include/framework/geometry/plane.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NPLANE__
|
||||
#define __NPLANE__
|
||||
|
||||
|
||||
#include "math/vector.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
@short Plane.
|
||||
ax + by + cz + d = 0
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
|
||||
class Plane
|
||||
{
|
||||
float d; ///< Distance to origin.
|
||||
Vector4 p, n; ///< Point in plane and normal.
|
||||
|
||||
public:
|
||||
|
||||
/// Return plane normal.
|
||||
inline const Vector4 &GetNormal() const
|
||||
{ return n; }
|
||||
|
||||
/*!
|
||||
@short Return point distance to plane.
|
||||
|
||||
Distance is signed, positive when the point is in front of the plane,
|
||||
negative otherwise.
|
||||
*/
|
||||
inline float DistanceToPlane(const Vector4 &p) const
|
||||
{ return p.Dot(n) + d; }
|
||||
|
||||
/// Set plane from point/normal and an optional transformation matrix.
|
||||
void Set(const Vector4 *_p, const Vector4 &_n, const Matrix4 * = 0);
|
||||
/// Set plane three vectors and an optional transformation matrix.
|
||||
void Set(const Vector4 _p[3], const Matrix4 * = 0);
|
||||
|
||||
Plane();
|
||||
Plane(const Vector4 &_p, const Vector4 &_n, const Matrix4 *_m = 0)
|
||||
{ Set(&_p, _n, _m); }
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NPLANE__
|
||||
112
include/framework/geometry/rect.h
Normal file
112
include/framework/geometry/rect.h
Normal file
@ -0,0 +1,112 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NRECT__
|
||||
#define __NRECT__
|
||||
|
||||
|
||||
#include "ntypes.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace NML {
|
||||
class File;
|
||||
class Tag;
|
||||
}
|
||||
|
||||
/*!
|
||||
@short Point.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
template <class T> struct Point
|
||||
{
|
||||
T x, y;
|
||||
|
||||
T operator [] (size_t n) const { return *(&x + n); }
|
||||
|
||||
void Set(T _x, T _y)
|
||||
{ x = _x; y = _y; }
|
||||
|
||||
Point(T ux, T uy) : x(ux), y(uy) {}
|
||||
Point() : x(0), y(0) {}
|
||||
};
|
||||
|
||||
typedef Point <int> iPoint;
|
||||
typedef Point <float> fPoint;
|
||||
|
||||
/*!
|
||||
@short Rectangle.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
template <class T> struct Rect
|
||||
{
|
||||
T sx, sy, ex, ey;
|
||||
|
||||
void SetWidth(T w) { ex = sx + w; }
|
||||
void SetHeight(T h) { ey = sy + h; }
|
||||
T GetWidth() const { return ex - sx; }
|
||||
T GetHeight() const { return ey - sy; }
|
||||
|
||||
Rect <T> operator * (T v) const
|
||||
{ return Rect <T> (sx * v, sy * v, ex * v, ey * v); }
|
||||
Rect <T> operator / (T v) const
|
||||
{ return Rect <T> (sx / v, sy / v, ex / v, ey / v); }
|
||||
|
||||
bool Inside(T x, T y) const
|
||||
{ return (x > sx) && (y > sy) && (x < ex) && (y < ey); }
|
||||
|
||||
bool FitsInside(const Rect <T> &b) const
|
||||
{ return (GetWidth() <= b.GetWidth()) && (GetHeight() <= b.GetHeight()); }
|
||||
|
||||
bool Intersect(const Rect <T> &b) const
|
||||
{ return ((ex < b.sx) || (ey < b.sy) || (sx > b.ex) || (sy > b.ey)) ? false : true; }
|
||||
|
||||
Rect <T> Intersection(const Rect <T> &b) const
|
||||
{
|
||||
T _sx = Types::Max(sx, b.sx), _sy = Types::Max(sy, b.sy),
|
||||
_ex = Types::Min(ex, b.ex), _ey = Types::Min(ey, b.ey);
|
||||
|
||||
T n_sx = Types::Min(_sx, _ex), n_sy = Types::Min(_sy, _ey),
|
||||
n_ex = Types::Max(_sx, _ex), n_ey = Types::Max(_sy, _ey);
|
||||
|
||||
return Rect <T> (_sx = n_sx, _sy = n_sy, _ex = n_ex, _ey = n_ey);
|
||||
}
|
||||
|
||||
Rect <T> Grow(T border) const
|
||||
{ return Rect <T> (sx - border, sy - border, ex + border, ey + border); }
|
||||
|
||||
void Set(T usx, T usy, T uex, T uey)
|
||||
{ sx = usx; sy = usy; ex = uex; ey = uey; }
|
||||
void Set(T ux = 0, T uy = 0)
|
||||
{ sx = ux; sy = uy; ex = ux; ey = uy; }
|
||||
|
||||
Rect <T> Offset(T x, T y) const
|
||||
{ return Rect <T> (sx + x, sy + y, ex + x, ey + y); }
|
||||
|
||||
Rect <float> AsFloat() const
|
||||
{ return Rect <float> (float(sx), float(sy), float(ex), float(ey)); }
|
||||
Rect <int> AsInt() const
|
||||
{ return Rect <int> (int(sx), int(sy), int(ex), int(ey)); }
|
||||
|
||||
NML::Tag *AsMetaTag(const char *id) const;
|
||||
bool FromMetaTag(NML::Tag &);
|
||||
|
||||
static Rect <T> FromWidthHeight(T sx, T sy, T w, T h)
|
||||
{ return Rect <T> (sx, sy, sx + w, sy + h); }
|
||||
|
||||
Rect(const Rect <T> &b) : sx(b.sx), sy(b.sy), ex(b.ex), ey(b.ey) {}
|
||||
Rect(T usx, T usy, T uex, T uey) : sx(usx), sy(usy), ex(uex), ey(uey) {}
|
||||
Rect(T usx, T usy) : sx(usx), ex(usx), sy(usy), ey(usy) {}
|
||||
Rect() : sx(0), sy(0), ex(0), ey(0) {}
|
||||
};
|
||||
|
||||
typedef Rect <int> iRect;
|
||||
typedef Rect <float> fRect;
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NRECT__
|
||||
59
include/framework/geometry/sat.h
Normal file
59
include/framework/geometry/sat.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NSAT__
|
||||
#define __NSAT__
|
||||
|
||||
|
||||
#include <float.h>
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace SAT {
|
||||
|
||||
/// SAT overlap test results.
|
||||
enum Overlap
|
||||
{
|
||||
Outside = 0,
|
||||
Inside, // B inside A
|
||||
Clipped
|
||||
};
|
||||
|
||||
/// Helper function to test overlap on a given axis.
|
||||
Overlap TestOverlap(const Vector4 &axis, int ca, const Vector4 *a, int cb, const Vector4 *b)
|
||||
{
|
||||
// A interval.
|
||||
float a_mn = FLT_MAX, a_mx = -FLT_MAX;
|
||||
for (int n = 0; n < ca; ++n)
|
||||
{
|
||||
float d = axis.Dot(a[n]);
|
||||
if (d < a_mn) a_mn = d;
|
||||
if (d > a_mx) a_mx = d;
|
||||
}
|
||||
|
||||
// B interval.
|
||||
float b_mn = FLT_MAX, b_mx = -FLT_MAX;
|
||||
for (int n = 0; n < cb; ++n)
|
||||
{
|
||||
float d = axis.Dot(b[n]);
|
||||
if (d < b_mn) b_mn = d;
|
||||
if (d > b_mx) b_mx = d;
|
||||
}
|
||||
|
||||
// Test overlap.
|
||||
if ((a_mx < b_mn) || (a_mn > b_mx))
|
||||
return Outside;
|
||||
if ((b_mn > a_mn) && (b_mx < a_mx))
|
||||
return Inside;
|
||||
|
||||
return Clipped;
|
||||
}
|
||||
|
||||
} // SAT
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NSAT__
|
||||
225
include/framework/math/matrix3.h
Normal file
225
include/framework/math/matrix3.h
Normal file
@ -0,0 +1,225 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NMATRIX3__
|
||||
#define __NMATRIX3__
|
||||
|
||||
|
||||
#include "math/vector.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
struct Quaternion;
|
||||
class Matrix4;
|
||||
|
||||
/*!
|
||||
@short 3x3 Matrix.
|
||||
This matrix class is column major.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
class Matrix3
|
||||
{
|
||||
static Matrix3 static_identity;
|
||||
|
||||
public:
|
||||
|
||||
NPLACEMENT_NEW(Matrix)
|
||||
|
||||
/// The matrix values.
|
||||
float m[3][3];
|
||||
|
||||
bool operator == (const Matrix3 &b) const
|
||||
{
|
||||
for (uint i = 0; i < 3; i++)
|
||||
for (uint j = 0; j < 3; j++)
|
||||
if (!Math::TestEqual(m[i][j], b.m[i][j]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator != (const Matrix3 &b) const
|
||||
{
|
||||
for (uint i = 0; i < 3; i++)
|
||||
for (uint j = 0; j < 3; j++)
|
||||
if (!Math::TestEqual(m[i][j], b.m[i][j]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Matrix3 operator + (const Matrix3 &b) const
|
||||
{
|
||||
Matrix3 r;
|
||||
for (uint j = 0; j < 3; j++)
|
||||
for (uint i = 0; i < 3; i++)
|
||||
r.m[i][j] = m[i][j] + b.m[i][j];
|
||||
return r;
|
||||
}
|
||||
|
||||
void operator += (const Matrix3 &b)
|
||||
{ *this = *this + b; }
|
||||
|
||||
void operator *= (const float k)
|
||||
{
|
||||
for (uint j = 0; j < 3; j++)
|
||||
for (uint i = 0; i < 3; i++)
|
||||
m[i][j] *= k;
|
||||
}
|
||||
void operator /= (const float k)
|
||||
{
|
||||
for (uint j = 0; j < 3; j++)
|
||||
for (uint i = 0; i < 3; i++)
|
||||
m[i][j] /= k;
|
||||
}
|
||||
|
||||
Matrix3 operator - (const Matrix3 &b) const
|
||||
{
|
||||
Matrix3 r;
|
||||
for (uint j = 0; j < 3; j++)
|
||||
for (uint i = 0; i < 3; i++)
|
||||
r.m[i][j] = m[i][j] - b.m[i][j];
|
||||
return r;
|
||||
}
|
||||
void operator -= (const Matrix3 &b)
|
||||
{ *this = *this - b; }
|
||||
|
||||
Vector4 operator * (const Vector4 &v) const
|
||||
{
|
||||
Vector4 o;
|
||||
o.x = v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2];
|
||||
o.y = v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2];
|
||||
o.z = v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2];
|
||||
o.w = 1;
|
||||
return o;
|
||||
}
|
||||
Matrix3 operator * (const Matrix3 &b) const
|
||||
{
|
||||
#define __M33M33(__I, __J) m[__I][0] * b.m[0][__J] + m[__I][1] * b.m[1][__J] + m[__I][2] * b.m[2][__J]
|
||||
return Matrix3 (
|
||||
__M33M33(0, 0), __M33M33(1, 0), __M33M33(2, 0),
|
||||
__M33M33(0, 1), __M33M33(1, 1), __M33M33(2, 1),
|
||||
__M33M33(0, 2), __M33M33(1, 2), __M33M33(2, 2)
|
||||
);
|
||||
}
|
||||
Matrix3 operator * (const float v) const
|
||||
{
|
||||
Matrix3 r;
|
||||
for (uint j = 0; j < 3; j++)
|
||||
for (uint i = 0; i < 3; i++)
|
||||
r.m[i][j] = m[i][j] * v;
|
||||
return r;
|
||||
}
|
||||
void operator *= (const Matrix3 &b)
|
||||
{ *this = (*this) * b; }
|
||||
Matrix3 operator / (const float v) const
|
||||
{
|
||||
Matrix3 r;
|
||||
for (uint j = 0; j < 3; j++)
|
||||
for (uint i = 0; i < 3; i++)
|
||||
r.m[i][j] = m[i][j] / v;
|
||||
return r;
|
||||
}
|
||||
|
||||
/// Apply to a set of vector objects.
|
||||
void Apply(Vector4 *o, const Vector4 *v, uint n = 1) const;
|
||||
|
||||
/// Compute the determinant of the matrix.
|
||||
float Det() const
|
||||
{
|
||||
return ((m[1][1] * m[2][2]) - (m[1][2] * m[2][1])) * m[0][0] +
|
||||
((m[1][2] * m[2][0]) - (m[1][0] * m[2][2])) * m[0][1] +
|
||||
((m[1][0] * m[2][1]) - (m[1][1] * m[2][0])) * m[0][2];
|
||||
}
|
||||
|
||||
/// Compute inverse matrix.
|
||||
bool Inverse(Matrix3 &i) const;
|
||||
|
||||
/// Return the transposed matrix.
|
||||
inline Matrix3 Transposed() const
|
||||
{
|
||||
return Matrix3
|
||||
(
|
||||
m[0][0], m[0][1], m[0][2],
|
||||
m[1][0], m[1][1], m[1][2],
|
||||
m[2][0], m[2][1], m[2][2]
|
||||
);
|
||||
}
|
||||
|
||||
/// Return the nth row.
|
||||
inline Vector4 GetRow(uint n) const { return Vector4(m[0][n], m[1][n], m[2][n]); }
|
||||
/// Return the nth column.
|
||||
inline Vector4 GetColumn(uint n) const { return Vector4(m[n][0], m[n][1], m[n][2]); }
|
||||
/// Set the nth row.
|
||||
void SetRow(uint n, const Vector4 &row);
|
||||
/// Set the nth column.
|
||||
void SetColumn(uint n, const Vector4 &col);
|
||||
|
||||
/// Set matrix values.
|
||||
void Set (
|
||||
float m00, float m10, float m20,
|
||||
float m01, float m11, float m21,
|
||||
float m02, float m12, float m22
|
||||
);
|
||||
/// Set matrix values.
|
||||
void Set(const Vector4 &u, const Vector4 &v, const Vector4 &w);
|
||||
|
||||
/// Return this matrix after normalization.
|
||||
Matrix3 Normalized() const;
|
||||
/// Normalize as orthonormal base.
|
||||
Matrix3 AsOrthonormalBase() const;
|
||||
/// Return an Euler orientation equivalent to this matrix.
|
||||
Vector4 AsEuler(Math::rOrder rorder = Math::rOrder_Default) const;
|
||||
|
||||
/// Vector matrix.
|
||||
static Matrix3 VectorMatrix(const Vector4 &v);
|
||||
/// Identity matrix.
|
||||
static Matrix3 &IdentityMatrix() { return static_identity; }
|
||||
/// Translation matrix.
|
||||
static Matrix3 TranslationMatrix(const Vector2 &t);
|
||||
static Matrix3 TranslationMatrix(const Vector4 &t);
|
||||
/// Scale matrix.
|
||||
static Matrix3 ScaleMatrix(const Vector2 &s);
|
||||
static Matrix3 ScaleMatrix(const Vector4 &s);
|
||||
/// Cross product matrix.
|
||||
static Matrix3 CrossProductMatrix(const Vector4 &v);
|
||||
|
||||
/// Rotation matrix around X axis.
|
||||
static Matrix3 RotationMatrixXAxis(float a);
|
||||
/// Rotation matrix around Y axis.
|
||||
static Matrix3 RotationMatrixYAxis(float a);
|
||||
/// Rotation matrix around Z axis.
|
||||
static Matrix3 RotationMatrixZAxis(float a);
|
||||
/*!
|
||||
@short From Orthonormal basis.
|
||||
|
||||
Transform an orthogonal basis formed by one or two vectors to a
|
||||
rotation matrix.
|
||||
@note Left-handed base, eg: u = {1,0,0}, v = {0,1,0}, w = {0,0,1}.
|
||||
*/
|
||||
static Matrix3 FromOrthonormalBasis(const Vector4 &w, const Vector4 *v = 0);
|
||||
/// From Euler triplet.
|
||||
static Matrix3 FromEuler(float x = 0, float y = 0, float z = 0, Math::rOrder rorder = Math::rOrder_Default);
|
||||
/// From Euler vector.
|
||||
static Matrix3 FromEuler(const Vector4 &euler, Math::rOrder rorder = Math::rOrder_Default);
|
||||
/// From matrix4.
|
||||
static Matrix3 FromMatrix4(const Matrix4 &mtx);
|
||||
|
||||
NML::Tag *AsMetaTag(const char *) const;
|
||||
bool FromMetaTag(NML::Tag &);
|
||||
|
||||
Matrix3(
|
||||
float m00 = 1, float m10 = 0, float m20 = 0,
|
||||
float m01 = 0, float m11 = 1, float m21 = 0,
|
||||
float m02 = 0, float m12 = 0, float m22 = 1
|
||||
)
|
||||
{ Set(m00, m10, m20, m01, m11, m21, m02, m12, m22); }
|
||||
Matrix3(const Vector4 &u, const Vector4 &v, const Vector4 &w)
|
||||
{ Set(u, v, w); }
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NMATRIX3__
|
||||
239
include/framework/math/matrix4.h
Normal file
239
include/framework/math/matrix4.h
Normal file
@ -0,0 +1,239 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NMATRIX4__
|
||||
#define __NMATRIX4__
|
||||
|
||||
|
||||
#include "math/vector.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
class Matrix3;
|
||||
|
||||
/*!
|
||||
@short 4x4 Matrix.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
class Matrix4
|
||||
{
|
||||
static Matrix4 static_identity;
|
||||
|
||||
public:
|
||||
|
||||
NPLACEMENT_NEW(Matrix)
|
||||
|
||||
/// The matrix values.
|
||||
float m[4][4];
|
||||
|
||||
bool operator == (const Matrix4 &b) const
|
||||
{
|
||||
for (uint i = 0; i < 4; i++)
|
||||
for (uint j = 0; j < 4; j++)
|
||||
if (!Math::TestEqual(m[i][j], b.m[i][j]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator != (const Matrix4 &b) const
|
||||
{
|
||||
for (uint i = 0; i < 4; i++)
|
||||
for (uint j = 0; j < 4; j++)
|
||||
if (!Math::TestEqual(m[i][j], b.m[i][j]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline Matrix4 operator * (const Matrix4 &b) const
|
||||
{
|
||||
#define __M44M44(__I, __J) m[__I][0] * b.m[0][__J] + m[__I][1] * b.m[1][__J] + m[__I][2] * b.m[2][__J] + m[__I][3] * b.m[3][__J]
|
||||
return Matrix4(
|
||||
__M44M44(0, 0), __M44M44(1, 0), __M44M44(2, 0), __M44M44(3, 0),
|
||||
__M44M44(0, 1), __M44M44(1, 1), __M44M44(2, 1), __M44M44(3, 1),
|
||||
__M44M44(0, 2), __M44M44(1, 2), __M44M44(2, 2), __M44M44(3, 2),
|
||||
__M44M44(0, 3), __M44M44(1, 3), __M44M44(2, 3), __M44M44(3, 3)
|
||||
);
|
||||
}
|
||||
const Matrix4 operator * (float v) const
|
||||
{
|
||||
Matrix4 r;
|
||||
for (uint j = 0; j < 4; ++j)
|
||||
for (uint i = 0; i < 4; ++i)
|
||||
r.m[i][j] = m[i][j] * v;
|
||||
return r;
|
||||
}
|
||||
|
||||
const Matrix4 operator + (const Matrix4 &b) const
|
||||
{
|
||||
Matrix4 r;
|
||||
for (uint j = 0; j < 4; j++)
|
||||
for (uint i = 0; i < 4; i++)
|
||||
r.m[i][j] = m[i][j] + b.m[i][j];
|
||||
return r;
|
||||
}
|
||||
|
||||
/// Return the nth row.
|
||||
inline Vector4 GetRow(uint n, bool w_to_one = true) const
|
||||
{ return Vector4(m[0][n], m[1][n], m[2][n], w_to_one ? 1 : m[3][n]); }
|
||||
/// Return the nth column.
|
||||
inline Vector4 GetColumn(uint n, bool w_to_one = true) const
|
||||
{ return Vector4(m[n][0], m[n][1], m[n][2], w_to_one ? 1 : m[n][3]); }
|
||||
/// Set the nth row.
|
||||
inline void SetRow(uint n, const Vector4 &r, bool w_to_one = true)
|
||||
{ m[0][n] = r.x; m[1][n] = r.y; m[2][n] = r.z; m[3][n] = w_to_one ? 1 : r.w; }
|
||||
/// Set the nth column.
|
||||
inline void SetColumn(uint n, const Vector4 &c, bool w_to_one = true)
|
||||
{ m[n][0] = c.x; m[n][1] = c.y; m[n][2] = c.z; m[n][3] = w_to_one ? 1 : c.w; }
|
||||
|
||||
bool Inverse(Matrix4 &out) const;
|
||||
/*!
|
||||
@short Return the inverse matrix using a fast approximation.
|
||||
@warning This function works only for standard 3d transformation
|
||||
matrices.
|
||||
*/
|
||||
Matrix4 InversedFast() const;
|
||||
/// Transpose matrix.
|
||||
Matrix4 Transposed() const
|
||||
{
|
||||
return Matrix4(
|
||||
m[0][0], m[0][1], m[0][2], m[0][3],
|
||||
m[1][0], m[1][1], m[1][2], m[1][3],
|
||||
m[2][0], m[2][1], m[2][2], m[2][3],
|
||||
m[3][0], m[3][1], m[3][2], m[3][3]
|
||||
);
|
||||
}
|
||||
/// Normalize matrix.
|
||||
Matrix4 AsOrthonormalBase() const;
|
||||
|
||||
/// Interpolate between two 4x4 transformation matrices.
|
||||
static Matrix4 LerpAsOrthonormalBase(const Matrix4 &a, const Matrix4 &b, float k, bool fast = false);
|
||||
|
||||
/// Decompose a transformation matrix into a position vector, a scale vector and a 3x3 rotation matrix.
|
||||
void Decompose(Vector4 *position, Vector4 *scale = 0, Matrix3 *rotation = 0) const;
|
||||
/// Decompose a transformation matrix into a position vector, a scale vector and a rotation vector.
|
||||
void Decompose(Vector4 *position, Vector4 *scale, Vector4 *rotation, Math::rOrder order = Math::rOrder_Default) const;
|
||||
|
||||
/// Apply to vector array.
|
||||
inline void Apply(Vector4 *o, const Vector4 *i, uint n = 1) const
|
||||
{
|
||||
for (uint c = 0; c < n; c++)
|
||||
{
|
||||
o[c].x = i[c].x * m[0][0] + i[c].y * m[0][1] + i[c].z * m[0][2] + i[c].w * m[0][3];
|
||||
o[c].y = i[c].x * m[1][0] + i[c].y * m[1][1] + i[c].z * m[1][2] + i[c].w * m[1][3];
|
||||
o[c].z = i[c].x * m[2][0] + i[c].y * m[2][1] + i[c].z * m[2][2] + i[c].w * m[2][3];
|
||||
o[c].w = i[c].x * m[3][0] + i[c].y * m[3][1] + i[c].z * m[3][2] + i[c].w * m[3][3];
|
||||
}
|
||||
}
|
||||
/// Apply upper-left 3x3 sub-matrix to vector array.
|
||||
inline void ApplyRotation(Vector4 *o, const Vector4 *i, uint n = 1) const
|
||||
{
|
||||
for (uint c = 0; c < n; c++)
|
||||
{
|
||||
o[c].x = i[c].x * m[0][0] + i[c].y * m[0][1] + i[c].z * m[0][2];
|
||||
o[c].y = i[c].x * m[1][0] + i[c].y * m[1][1] + i[c].z * m[1][2];
|
||||
o[c].z = i[c].x * m[2][0] + i[c].y * m[2][1] + i[c].z * m[2][2];
|
||||
o[c].w = 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
/// Set values.
|
||||
void Set (
|
||||
float m00, float m10, float m20, float m30,
|
||||
float m01, float m11, float m21, float m31,
|
||||
float m02, float m12, float m22, float m32,
|
||||
float m03, float m13, float m23, float m33
|
||||
)
|
||||
{
|
||||
m[0][0] = m00; m[1][0] = m10; m[2][0] = m20; m[3][0] = m30;
|
||||
m[0][1] = m01; m[1][1] = m11; m[2][1] = m21; m[3][1] = m31;
|
||||
m[0][2] = m02; m[1][2] = m12; m[2][2] = m22; m[3][2] = m32;
|
||||
m[0][3] = m03; m[1][3] = m13; m[2][3] = m23; m[3][3] = m33;
|
||||
}
|
||||
|
||||
/// Identity matrix.
|
||||
static const Matrix4 &IdentityMatrix()
|
||||
{ return static_identity; }
|
||||
|
||||
/// Translation matrix.
|
||||
static Matrix4 TranslationMatrix(const Vector4 &t);
|
||||
/// Scale matrix.
|
||||
static Matrix4 ScaleMatrix(const Vector4 &s);
|
||||
/// From matrix3.
|
||||
static Matrix4 FromMatrix3(const Matrix3 &mtx);
|
||||
/// Position/scale/rotation/offset matrix.
|
||||
static Matrix4 TransformationMatrix(const Vector4 &p, const Vector4 &r, const Vector4 &s, const Vector4 *o = 0);
|
||||
/// Position/scale/rotation/offset matrix.
|
||||
static Matrix4 TransformationMatrix(const Vector4 &p, const Matrix3 &r, const Vector4 &s, const Vector4 *o = 0);
|
||||
|
||||
NML::Tag *AsMetaTag(const char *id) const;
|
||||
bool FromMetaTag(NML::Tag &);
|
||||
|
||||
Matrix4(
|
||||
float m00, float m10, float m20, float m30,
|
||||
float m01, float m11, float m21, float m31,
|
||||
float m02, float m12, float m22, float m32,
|
||||
float m03, float m13, float m23, float m33
|
||||
)
|
||||
{
|
||||
m[0][0] = m00; m[1][0] = m10; m[2][0] = m20; m[3][0] = m30;
|
||||
m[0][1] = m01; m[1][1] = m11; m[2][1] = m21; m[3][1] = m31;
|
||||
m[0][2] = m02; m[1][2] = m12; m[2][2] = m22; m[3][2] = m32;
|
||||
m[0][3] = m03; m[1][3] = m13; m[2][3] = m23; m[3][3] = m33;
|
||||
}
|
||||
Matrix4() {}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
@short 4x4 matrix with inverse.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
class Matrix4WithInverse
|
||||
{
|
||||
protected:
|
||||
|
||||
NPLACEMENT_NEW(Matrix)
|
||||
|
||||
Matrix4 matrix,
|
||||
imatrix;
|
||||
|
||||
/// Commit a matrix change.
|
||||
void Commit();
|
||||
|
||||
public:
|
||||
|
||||
/// Return the matrix inverse.
|
||||
const Matrix4 &Get() const;
|
||||
/// Return the matrix inverse.
|
||||
const Matrix4 &GetInverse() const;
|
||||
|
||||
/// Set matrix.
|
||||
void Set(const Matrix4 &m);
|
||||
|
||||
/// Return the nth row.
|
||||
Vector4 GetRow(uint n, bool w_1 = true) const;
|
||||
/// Return the nth column.
|
||||
Vector4 GetColumn(uint n, bool w_1 = true) const;
|
||||
/// Set the nth row.
|
||||
void SetRow(uint n, const Vector4 &row, bool w_1 = true);
|
||||
/// Set the nth column.
|
||||
void SetColumn(uint n, const Vector4 &col, bool w_1 = true);
|
||||
|
||||
bool FromMetaTag(NML::Tag &tag);
|
||||
NML::Tag *AsMetaTag(const char *id) const;
|
||||
|
||||
Matrix4WithInverse()
|
||||
{
|
||||
matrix = Matrix4::IdentityMatrix();
|
||||
imatrix = Matrix4::IdentityMatrix();
|
||||
}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NMATRIX4__
|
||||
|
||||
107
include/framework/math/quaternion.h
Normal file
107
include/framework/math/quaternion.h
Normal file
@ -0,0 +1,107 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NQUATERNION__
|
||||
#define __NQUATERNION__
|
||||
|
||||
|
||||
#include "math/nmath.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
struct Vector4;
|
||||
class Matrix3;
|
||||
|
||||
namespace NML {
|
||||
class File;
|
||||
class Tag;
|
||||
}
|
||||
|
||||
/*!
|
||||
@short Quaternion.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct Quaternion
|
||||
{
|
||||
float x, y, z, w;
|
||||
|
||||
void operator += (const Quaternion &b) { x += b.x; y += b.y; z += b.z; w += b.w; };
|
||||
void operator += (float k) { x += k; y += k; z += k; w += k; };
|
||||
void operator -= (const Quaternion &b) { x -= b.x; y -= b.y; z -= b.z; w -= b.w; };
|
||||
void operator -= (float k) { x -= k; y -= k; z -= k; w -= k; };
|
||||
void operator *= (const Quaternion &b)
|
||||
{
|
||||
Quaternion t = *this;
|
||||
w = t.w * b.w - (t.x * b.x + t.y * b.y + t.z * b.z);
|
||||
x = t.w * b.x + b.w * t.x + t.y * b.z - t.z * b.y;
|
||||
y = t.w * b.y + b.w * t.y + t.z * b.x - t.x * b.z;
|
||||
z = t.w * b.z + b.w * t.z + t.x * b.y - t.y * b.x;
|
||||
};
|
||||
void operator *= (float k) { x *= k; y *= k; z *= k; w *= k; };
|
||||
void operator /= (float k) { k = 1.f / k; x *= k; y *= k; z *= k; w *= k; };
|
||||
|
||||
Quaternion operator + (const Quaternion &b) const
|
||||
{ return Quaternion(x + b.x, y + b.y, z + b.z, w + b.w); }
|
||||
Quaternion operator + (float v) const
|
||||
{ return Quaternion(x + v, y + v, z + v, w + v); }
|
||||
Quaternion operator - (const Quaternion &b) const
|
||||
{ return Quaternion(x - b.x, y - b.y, z - b.z, w - b.w); }
|
||||
Quaternion operator - (float v) const
|
||||
{ return Quaternion(x - v, y - v, z - v, w - v); }
|
||||
Quaternion operator * (const Quaternion &b) const
|
||||
{
|
||||
return Quaternion (
|
||||
w * b.x + b.w * x + y * b.z - z * b.y,
|
||||
w * b.y + b.w * y + z * b.x - x * b.z,
|
||||
w * b.z + b.w * z + x * b.y - y * b.x,
|
||||
w * b.w - (x * b.x + y * b.y + z * b.z)
|
||||
);
|
||||
}
|
||||
Quaternion operator * (float v) const
|
||||
{ return Quaternion(x * v, y * v, z * v, w * v); }
|
||||
Quaternion operator / (float v) const
|
||||
{ v = 1.f / v; return Quaternion(x * v, y * v, z * v, w * v); }
|
||||
|
||||
/// Dot product.
|
||||
float Dot(const Quaternion &b) const
|
||||
{ return x * b.x + y * b.y + z * b.z + w * b.w; }
|
||||
|
||||
/// Normalize quaternion.
|
||||
Quaternion Normalize() const;
|
||||
/// Inverse quaternion.
|
||||
Quaternion Inverse() const;
|
||||
/// To rotation matrix.
|
||||
Matrix3 AsMatrix3() const;
|
||||
|
||||
/// Distance to quaternion.
|
||||
static float Distance(const Quaternion &a, const Quaternion &b);
|
||||
/// Slerp.
|
||||
static Quaternion Slerp(float t, const Quaternion &a, const Quaternion &b);
|
||||
|
||||
/// From Euler angle.
|
||||
static Quaternion FromEuler(float x, float y, float z, Math::rOrder rorder = Math::rOrder_Default);
|
||||
/// Get an orientation from a 'look at' vector (look_at = to - from).
|
||||
static Quaternion LookAt(const Vector4 &at);
|
||||
/// From matrix3.
|
||||
static Quaternion FromMatrix3(const Matrix3 &m);
|
||||
/// From axis-angle.
|
||||
static Quaternion FromAxisAngle(float angle, float x, float y, float z);
|
||||
|
||||
/// Set quaternion values.
|
||||
void Set(float _x = 0, float _y = 0, float _z = 0, float _w = 1.f)
|
||||
{ x = _x; y = _y; z = _z; w = _w; }
|
||||
|
||||
NML::Tag *AsMetaTag(const char *id) const;
|
||||
bool FromMetaTag(NML::Tag &tag);
|
||||
|
||||
Quaternion(float _x = 0, float _y = 0, float _z = 0, float _w = 1.f)
|
||||
{ Set(_x, _y, _z, _w); }
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NQUATERNION__
|
||||
301
include/framework/math/vector.h
Normal file
301
include/framework/math/vector.h
Normal file
@ -0,0 +1,301 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NVECTOR__
|
||||
#define __NVECTOR__
|
||||
|
||||
|
||||
#include "math/nmath.h"
|
||||
#include "alloc/ialloc.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
class Matrix3;
|
||||
class Matrix4;
|
||||
|
||||
namespace NML {
|
||||
class File;
|
||||
class Tag;
|
||||
}
|
||||
|
||||
/*!
|
||||
@short Vector 2d template class.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
template <class T> struct tVector2
|
||||
{
|
||||
NPLACEMENT_NEW(Vector)
|
||||
|
||||
T x, y;
|
||||
|
||||
inline bool operator == (const tVector2 <T> &b) const { return (x == b.x) && (y == b.y); }
|
||||
inline bool operator != (const tVector2 <T> &b) const { return (x != b.x) || (y != b.y); }
|
||||
|
||||
inline void operator += (const tVector2 <T> &b) { x += b.x; y += b.y; }
|
||||
inline void operator += (const float k) { x += k; y += k; }
|
||||
inline void operator -= (const tVector2 <T> &b) { x -= b.x; y -= b.y; }
|
||||
inline void operator -= (const float k) { x -= k; y -= k; }
|
||||
inline void operator *= (const tVector2 <T> &b) { x *= b.x; y *= b.y; }
|
||||
inline void operator *= (const float k) { x *= k; y *= k; }
|
||||
inline void operator /= (const tVector2 <T> &b) { x /= b.x; y /= b.y; }
|
||||
inline void operator /= (const float k) { x /= k; y /= k; }
|
||||
|
||||
inline tVector2 <T> operator + (const tVector2 <T> &b) const { return tVector2 <T> (x + b.x, y + b.y); }
|
||||
inline tVector2 <T> operator + (const T v) const { return tVector2 <T> (x + v, y + v); }
|
||||
inline tVector2 <T> operator - (const tVector2 <T> &b) const { return tVector2 <T> (x - b.x, y - b.y); }
|
||||
inline tVector2 <T> operator - (const T v) const { return tVector2 <T> (x - v, y - v); }
|
||||
inline tVector2 <T> operator * (const tVector2 <T> &b) const { return tVector2 <T> (x * b.x, y * b.y); }
|
||||
inline tVector2 <T> operator * (const T v) const { return tVector2 <T> (x * v, y * v); }
|
||||
inline tVector2 <T> operator / (const tVector2 <T> &b) const { return tVector2 <T> (x / b.x, y / b.y); }
|
||||
inline tVector2 <T> operator / (const T v) const { return tVector2 <T> (x / v, y / v); }
|
||||
|
||||
tVector2 <T> operator * (const Matrix3 &m) const;
|
||||
|
||||
/// Squared vector length.
|
||||
inline float Len2() const { return (float)(x * x + y * y); }
|
||||
/// Vector length.
|
||||
inline float Len() const { return Math::Sqrt((float)(x * x + y * y)); }
|
||||
|
||||
/// Normalize this vector.
|
||||
inline void Normalize() { float l = Len(); if (l) { float k = 1.f / l; x *= k; y *= k; } }
|
||||
/// Normalize vector.
|
||||
inline tVector2 <T> Normalized() const
|
||||
{
|
||||
float k = 1.f / Len();
|
||||
return tVector2 <T>(x * k, y * k);
|
||||
}
|
||||
|
||||
/// Reversed vector.
|
||||
inline tVector2 <T> Reversed() const
|
||||
{ return tVector2 <T> (-x, -y); }
|
||||
|
||||
/// Vector squared distance.
|
||||
static float Dist2(const tVector2 &a, const tVector2 &b)
|
||||
{ return ((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y)); }
|
||||
/// Vector distance.
|
||||
static float Dist(const tVector2 &a, const tVector2 &b)
|
||||
{ return Math::Sqrt((float)((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y))); }
|
||||
|
||||
/// Set vector 2D components.
|
||||
inline void Set(const T a, const T b) { x = a; y = b; }
|
||||
|
||||
tVector2 <T> (T a, T b) { Set(a, b); }
|
||||
tVector2 <T> () { Set(0, 0); }
|
||||
};
|
||||
|
||||
typedef tVector2 <float> Vector2;
|
||||
|
||||
/*!
|
||||
@short 4-Component vector
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct Vector4
|
||||
{
|
||||
NPLACEMENT_NEW(Vector)
|
||||
|
||||
float x, y, z, w;
|
||||
|
||||
inline bool operator == (const Vector4 &b) const { return Math::TestEqual(x, b.x) && Math::TestEqual(y, b.y) && Math::TestEqual(z, b.z); }
|
||||
inline bool operator != (const Vector4 &b) const { return !Math::TestEqual(x, b.x) || !Math::TestEqual(y, b.y) || !Math::TestEqual(z, b.z); }
|
||||
|
||||
inline void operator += (const Vector4 &b) { x += b.x; y += b.y; z += b.z; };
|
||||
inline void operator += (const float k) { x += k; y += k; z += k; };
|
||||
inline void operator -= (const Vector4 &b) { x -= b.x; y -= b.y; z -= b.z; };
|
||||
inline void operator -= (const float k) { x -= k; y -= k; z -= k; };
|
||||
inline void operator *= (const Vector4 &b) { x *= b.x; y *= b.y; z *= b.z; };
|
||||
inline void operator *= (const float k) { x *= k; y *= k; z *= k; };
|
||||
inline void operator /= (const Vector4 &b) { x /= b.x; y /= b.y; z /= b.z; };
|
||||
inline void operator /= (const float k) { float k_ = k ? 1 / k : 0; x *= k_; y *= k_; z *= k_; };
|
||||
|
||||
inline Vector4 operator + (const Vector4 &b) const { return Vector4(x + b.x, y + b.y, z + b.z); }
|
||||
inline Vector4 operator + (const float v) const { return Vector4(x + v, y + v, z + v); }
|
||||
inline Vector4 operator - (const Vector4 &b) const { return Vector4(x - b.x, y - b.y, z - b.z); }
|
||||
inline Vector4 operator - (const float v) const { return Vector4(x - v, y - v, z - v); }
|
||||
inline Vector4 operator * (const Vector4 &b) const { return Vector4(x * b.x, y * b.y, z * b.z); }
|
||||
inline Vector4 operator * (const float v) const { return Vector4(x * v, y * v, z * v); }
|
||||
inline Vector4 operator / (const Vector4 &b) const { return Vector4(x / b.x, y / b.y, z / b.z); }
|
||||
inline Vector4 operator / (const float v) const { float i = v ? 1 / v : 0; return Vector4(x * i, y * i, z * i); }
|
||||
|
||||
inline float operator [] (size_t n) const { return (&x)[n]; }
|
||||
inline float &operator [] (size_t n) { return (&x)[n]; }
|
||||
|
||||
inline Vector4 SafeDivided(const Vector4 &b) const
|
||||
{ return Vector4(b.x ? x / b.x : 0, b.y ? y / b.y : 0, b.z ? z / b.z : 0); }
|
||||
|
||||
/// Set vector components.
|
||||
inline void Set(float x_, float y_, float z_, float w_)
|
||||
{ x = x_; y = y_; z = z_; w = w_; }
|
||||
inline void Set(float x_ = 0.f, float y_ = 0.f, float z_ = 0.f) // Used to provide script overload.
|
||||
{ x = x_; y = y_; z = z_; w = 1.0f; }
|
||||
inline void Set(Vector4 &v)
|
||||
{ x = v.x; y = v.y; z = v.z; w = v.w; }
|
||||
|
||||
/// Dot product.
|
||||
inline float Dot(const Vector4 &b) const
|
||||
{ return x * b.x + y * b.y + z * b.z; }
|
||||
/// Cross product.
|
||||
inline Vector4 Cross(const Vector4 &b) const
|
||||
{ return Vector4(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); }
|
||||
|
||||
void operator *= (const Matrix4 &);
|
||||
Vector4 operator * (const Matrix4 &) const;
|
||||
void operator *= (const Matrix3 &);
|
||||
Vector4 operator * (const Matrix3 &) const;
|
||||
|
||||
/// Reverse this vector.
|
||||
inline void Reverse() { x = -x; y = -y; z = -z; }
|
||||
/// Inverse vector.
|
||||
inline void Inverse() { x = x ? 1.f / x : 0; y = y ? 1.f / y : 0; z = z ? 1.f / z : 0; }
|
||||
|
||||
/// Normalize this vector.
|
||||
inline void Normalize() { float l = Len(); if (l) { float k = 1.f / l; x *= k; y *= k; z *= k; } }
|
||||
/// Normalize vector.
|
||||
inline Vector4 Normalized() const
|
||||
{
|
||||
float l = Len();
|
||||
float k = l ? 1.f / l : 1.f;
|
||||
return Vector4(x * k, y * k, z * k);
|
||||
}
|
||||
|
||||
/// Clamp vector components to [min;max].
|
||||
Vector4 Clamped(float min, float max) const;
|
||||
/// Clamp vector components to [min;max].
|
||||
Vector4 Clamped(const Vector4 &min, const Vector4 &max) const;
|
||||
/// Clamp vector magnitude to [min;max].
|
||||
Vector4 ClampedMagnitude(float min, float max) const;
|
||||
|
||||
/// Return the opposite vector to this vector.
|
||||
inline Vector4 Reversed() const
|
||||
{ return Vector4(-x, -y, -z); }
|
||||
/// Return the inverse vector to this vector.
|
||||
inline Vector4 Inversed() const
|
||||
{ return Vector4(1.f / x, 1.f / y, 1.f / z); }
|
||||
/// Absolute vector.
|
||||
Vector4 Abs() const;
|
||||
/// Sign vector.
|
||||
inline Vector4 Sign() const
|
||||
{ return Vector4(x < 0.f ? -1.f : 1.f, y < 0.f ? -1.f : 1.f, z < 0.f ? -1.f : 1.f); }
|
||||
|
||||
/// Maximum of two vectors.
|
||||
static Vector4 Maximum(const Vector4 &a, const Vector4 &b)
|
||||
{ return Vector4(a.x > b.x ? a.x : b.x, a.y > b.y ? a.y : b.y, a.z > b.z ? a.z : b.z); }
|
||||
/// Minimum of two vectors.
|
||||
static Vector4 Minimum(const Vector4 &a, const Vector4 &b)
|
||||
{ return Vector4(a.x < b.x ? a.x : b.x, a.y < b.y ? a.y : b.y, a.z < b.z ? a.z : b.z); }
|
||||
|
||||
/*!
|
||||
@short Reflect vector.
|
||||
@note Vector must be normalized.
|
||||
*/
|
||||
inline Vector4 Reflected(const Vector4 &n) const
|
||||
{
|
||||
Vector4 rv = Reversed();
|
||||
return n * (2.f * rv.Dot(n)) - rv;
|
||||
}
|
||||
/*!
|
||||
@short Refract vector.
|
||||
@note Vector must be normalized.
|
||||
*/
|
||||
inline Vector4 Refracted(const Vector4 &n, float kin = 1, float kout = 1) const
|
||||
{
|
||||
const float k = kin / kout;
|
||||
return (*this) * k + n * (k - 1.f);
|
||||
}
|
||||
|
||||
/// Squared vector length.
|
||||
inline float Len2() const { return (float)(x * x + y * y + z * z); }
|
||||
/// Vector length.
|
||||
inline float Len() const { return Math::Sqrt((float)(x * x + y * y + z * z)); }
|
||||
/// Hash vector.
|
||||
int Hash() const;
|
||||
|
||||
Vector4 Floor() const;
|
||||
Vector4 Ceil() const;
|
||||
|
||||
/*!
|
||||
@short Return a random vector.
|
||||
@note w component is not randomized but set to 1.
|
||||
*/
|
||||
static Vector4 Random(float min = -1, float max = 1);
|
||||
/// Vector squared distance.
|
||||
static float Dist2(const Vector4 &a, const Vector4 &b)
|
||||
{ return ((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y) + (b.z - a.z) * (b.z - a.z)); }
|
||||
/// Vector distance.
|
||||
static float Dist(const Vector4 &a, const Vector4 &b)
|
||||
{ return Math::Sqrt((float)((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y) + (b.z - a.z) * (b.z - a.z))); }
|
||||
/*!
|
||||
@short Vector base to Euler.
|
||||
@note base convention u = {0,0,1}, v = {1,0,0}, second axis is optional.
|
||||
*/
|
||||
static void BaseToEuler(Vector4 &euler, Vector4 &u, Vector4 *v = NULL);
|
||||
|
||||
/*!
|
||||
@short Return a vector which is facing a given direction.
|
||||
|
||||
Returns a copy of this vector if it is already facing the given
|
||||
direction or the opposite of this vector otherwise.
|
||||
*/
|
||||
Vector4 FaceForward(Vector4 &dir);
|
||||
|
||||
NML::Tag *AsMetaTag(const char *id, bool full_dump = false) const;
|
||||
bool FromMetaTag(NML::Tag &tag);
|
||||
|
||||
Vector4(float a, float b, float c, float d = 1) : x(a), y(b), z(c), w(d) {}
|
||||
Vector4(const tVector2 <float> &v2) : x(v2.x), y(v2.y), z(1), w(1) {}
|
||||
Vector4(const tVector2 <int> &v2) : x(float(v2.x)), y(float(v2.y)), z(1), w(1) {}
|
||||
Vector4() {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#define Vec3Set(v, a, b, c) { (v).x = a; (v).y = b; (v).z = c; }
|
||||
|
||||
#define Vec3Len2(v) ((v).x * (v).x + (v).y * (v).y + (v).z * (v).z)
|
||||
#define Vec3Len(v) Math::Sqrt((float)Vec3Len2(v))
|
||||
|
||||
#define Vec3Add(r, a, b) { (r).x = (a).x + (b).x; (r).y = (a).y + (b).y; (r).z = (a).z + (b).z; }
|
||||
#define Vec3AddConst(r, a, k) { (r).x = (a).x + k; (r).y = (a).y + k; (r).z = (a).z + k; }
|
||||
#define Vec3Sub(r, a, b) { (r).x = (a).x - (b).x; (r).y = (a).y - (b).y; (r).z = (a).z - (b).z; }
|
||||
#define Vec3SubConst(r, a, k) { (r).x = (a).x - k; (r).y = (a).y - k; (r).z = (a).z - k; }
|
||||
#define Vec3Mul(r, a, b) { (r).x = (a).x * (b).x; (r).y = (a).y * (b).y; (r).z = (a).z * (b).z; }
|
||||
#define Vec3MulConst(r, a, k) { float _k = k; (r).x = (a).x * _k; (r).y = (a).y * _k; (r).z = (a).z * _k; }
|
||||
#define Vec3Div(r, a, b) { (r).x = (a).x / (b).x; (r).y = (a).y / (b).y; (r).z = (a).z / (b).z; }
|
||||
#define Vec3DivConst(r, a, k) { float ik = 1.f / k; (r).x = (a).x * ik; (r).y = (a).y * ik; (r).z = (a).z * ik; }
|
||||
|
||||
#define Vec3Inc(r, a) { (r).x += (a).x; (r).y += (a).y; (r).z += (a).z; }
|
||||
#define Vec3IncConst(r, k) { (r).x += k; (r).y += k; (r).z += k; }
|
||||
#define Vec3Dec(r, a) { (r).x -= (a).x; (r).y -= (a).y; (r).z -= (a).z; }
|
||||
#define Vec3DecConst(r, k) { (r).x -= k; (r).y -= k; (r).z -= k; }
|
||||
#define Vec3Scale(r, a) { (r).x *= (a).x; (r).y *= (a).y; (r).z *= (a).z; }
|
||||
#define Vec3ScaleConst(r, k) { float _k = k; (r).x *= _k; (r).y *= _k; (r).z *= _k; }
|
||||
#define Vec3Shrink(r, a) { (r).x /= (a).x; (r).y /= (a).y; (r).z /= (a).z; }
|
||||
#define Vec3ShrinkConst(r, k) { float ik = 1.f / k; (r).x *= ik; (r).y *= ik; (r).z *= ik; }
|
||||
|
||||
#define Vec3Dot(a, b) ((a).x * (b).x + (a).y * (b).y + (a).z * (b).z)
|
||||
#define Vec3Cross(r, a, b) {\
|
||||
(r).x = (a).y * (b).z - (a).z * (b).y;\
|
||||
(r).y = (a).z * (b).x - (a).x * (b).z;\
|
||||
(r).z = (a).x * (b).y - (a).y * (b).x;\
|
||||
}
|
||||
|
||||
#define Vec3Clamp(v, a, b) {\
|
||||
if ((v).x < a) (v).x = a; else if ((v).x > b) (v).x = b;\
|
||||
if ((v).x < a) (v).x = a; else if ((v).x > b) (v).x = b;\
|
||||
if ((v).x < a) (v).x = a; else if ((v).x > b) (v).x = b;\
|
||||
}
|
||||
#define Vec3ClampMag(v, m) {\
|
||||
const float m2 = (m) * (m);\
|
||||
const float l2 = Vec3Len2(v);\
|
||||
if (l2 > m2)\
|
||||
{\
|
||||
const float k = Math::Sqrt((float)(m2 / l2));\
|
||||
Vec3ScaleConst(v, k);\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
#endif // __NVECTOR__
|
||||
50
include/framework/math/vector_nml.h
Normal file
50
include/framework/math/vector_nml.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NVECTORNML__
|
||||
#define __NVECTORNML__
|
||||
|
||||
|
||||
#include "metafile/nml.h"
|
||||
#include "math/vector.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <class T> NML::Tag *tVectorAsMetaTag(const tVector2 <T> &v, const char *id)
|
||||
{
|
||||
NML::Tag *root = id ? new NML::Tag(id) : new NML::Tag("Vector2");
|
||||
|
||||
if (root)
|
||||
{
|
||||
root->AddChild("X", v.x);
|
||||
root->AddChild("Y", v.y);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
template <class T> bool tVectorFromMetaTag(tVector2 <T> &v, NML::Tag &tag)
|
||||
{
|
||||
NML::Tag *t;
|
||||
List <NML::Tag *> ::Iterator i(tag.GetTags().GetRoot());
|
||||
|
||||
if ((t = i.ObjectPtr()) == NULL)
|
||||
return false;
|
||||
v.x = t->GetReal();
|
||||
++i;
|
||||
|
||||
if ((t = i.ObjectPtr()) == NULL)
|
||||
return false;
|
||||
v.y = t->GetReal();
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NVECTORNML__
|
||||
224
include/framework/metafile/nml.h
Normal file
224
include/framework/metafile/nml.h
Normal file
@ -0,0 +1,224 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NMETALANG__
|
||||
#define __NMETALANG__
|
||||
|
||||
|
||||
#include "data/nvariant.h"
|
||||
#include "container/nlist.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace IO { class Handle; }
|
||||
|
||||
namespace NML {
|
||||
class Tag;
|
||||
class File;
|
||||
|
||||
static const int version = 1;
|
||||
|
||||
/// Metatag.
|
||||
class Tag
|
||||
{
|
||||
friend struct Parser;
|
||||
friend class File;
|
||||
|
||||
protected:
|
||||
|
||||
/// Locate a tag through its path.
|
||||
static Tag *GetTagEx(const List <Tag *> &tag, const char *path, const File *root = 0, bool verbose = false);
|
||||
|
||||
List <Tag *> tags;
|
||||
|
||||
Variant value;
|
||||
|
||||
public:
|
||||
|
||||
NPLACEMENT_NEW(Metatag)
|
||||
|
||||
String name;
|
||||
|
||||
/// Get this tag parent by exploring a given tag hierarchy.
|
||||
Tag *GetParent(Tag *) const;
|
||||
|
||||
/// Get value.
|
||||
Variant &GetValue() { return value; }
|
||||
const Variant &GetValue() const { return value; }
|
||||
|
||||
/// Remove a child tag from this tag.
|
||||
bool RemoveTag(Tag *t) { return tags.Remove(t); }
|
||||
/// Delete all child tags.
|
||||
uint DeleteChildren(const char *filter = 0);
|
||||
/// Get child count.
|
||||
uint GetChildCount() const { return tags.GetCount(); }
|
||||
/// Return the tag children list.
|
||||
const List <Tag *> &GetTags() const { return tags; }
|
||||
|
||||
/// Add child to tag.
|
||||
Tag *AddChild(Tag *);
|
||||
Tag *AddChild(const char *);
|
||||
Tag *AddChild(const char *, bool);
|
||||
Tag *AddChild(const char *, int);
|
||||
Tag *AddChild(const char *, uint);
|
||||
Tag *AddChild(const char *, float);
|
||||
Tag *AddChild(const char *, const char *);
|
||||
Tag *AddChild(const char *, void *, size_t);
|
||||
|
||||
/// Return tag child.
|
||||
Tag *GetTag(const char *path, const File * = 0, bool verbose = false) const;
|
||||
/// Return the tag at a given path only if it matches the required type.
|
||||
Tag *GetTypedTag(const char *path, Variant::Type, const File * = 0, bool verbose = false) const;
|
||||
|
||||
bool GetBool() const { bool v; if (value.Get(v)) return v; return false; }
|
||||
int GetInteger() const { return value.i_value; }
|
||||
uint GetUnsigned() const { return value.u_value; }
|
||||
const char *GetString() const { return value.s_value; }
|
||||
float GetReal() const { return value.f_value; }
|
||||
|
||||
void SetBool(bool v) { value = v; }
|
||||
void SetInteger(int v) { value = v; }
|
||||
void SetUnsigned(uint v) { value = v; }
|
||||
void SetString(const char *v) { value = v; }
|
||||
void SetReal(float v) { value = v; }
|
||||
|
||||
Variant::Type GetType() const { return value.GetType(); }
|
||||
|
||||
/// Clone a tag and optionally recurse and clone its children.
|
||||
bool Clone(const Tag &src, bool recursive = true);
|
||||
/// Clone this tag and optionally recurse and clone its children.
|
||||
Tag *Clone(bool recursive = true) const;
|
||||
|
||||
/// Free the tag data, set its type to nVariant::VariantNone.
|
||||
void Free();
|
||||
|
||||
Tag() {}
|
||||
Tag(const char *n) : name(n) {}
|
||||
Tag(const char *n, bool v) : name(n), value(v) {}
|
||||
Tag(const char *n, int v) : name(n), value(v) {}
|
||||
Tag(const char *n, uint v) : name(n), value(v) {}
|
||||
Tag(const char *n, float v) : name(n), value(v) {}
|
||||
Tag(const char *n, const char *v) : name(n), value(v) {}
|
||||
Tag(const char *n, void *data, size_t size) : name(n), value(data, size) {}
|
||||
|
||||
~Tag();
|
||||
};
|
||||
|
||||
/*!
|
||||
@short Meta file.
|
||||
|
||||
A metafile contain the whole database in memory.
|
||||
This class is not meant to be used with heavy databases.
|
||||
|
||||
Tags can be accessed using tag paths. A tag path is formatted as follow:
|
||||
"root:node:...:tag;".
|
||||
|
||||
@note The closing hyphen is not required but warnings will be sent to the
|
||||
log if you don't use it. The node delimiter ':' can be repeated any
|
||||
number of time between nodes with no effect (eg: ":::node1::node2:;").
|
||||
By definition a file is a node tag and cannot have a value.
|
||||
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
class File
|
||||
{
|
||||
friend struct Parser;
|
||||
|
||||
public:
|
||||
|
||||
enum Binary
|
||||
{
|
||||
Binary_UU = 0, ///< UUEncoded.
|
||||
Binary_yEnc ///< yEncoded.
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
List <Tag *> tags;
|
||||
Binary binary_method; ///< Binary encoding method.
|
||||
|
||||
public:
|
||||
|
||||
String name;
|
||||
|
||||
/// Get the file ASCII binary encoding method.
|
||||
Binary GetBinaryMethod() const { return binary_method; }
|
||||
|
||||
const List <Tag *> &GetTags() const { return tags; }
|
||||
|
||||
uint GetRootCount() const { return tags.GetCount(); }
|
||||
|
||||
void Clear() { ListDeleteAllPtr(Tag *, tags); }
|
||||
bool isEmpty() const { return asbool(GetRootCount() == 0); }
|
||||
|
||||
/// Add a root tag to the file.
|
||||
Tag *AddRoot(Tag *);
|
||||
Tag *AddRoot(const char *);
|
||||
Tag *AddRoot(const char *, bool);
|
||||
Tag *AddRoot(const char *, int);
|
||||
Tag *AddRoot(const char *, float);
|
||||
Tag *AddRoot(const char *, const char *);
|
||||
Tag *AddRoot(const char *, void *, size_t);
|
||||
|
||||
/// Unlink a root tag from file.
|
||||
bool UnlinkRoot(Tag *);
|
||||
|
||||
/// Return the tag at a given path.
|
||||
Tag *GetTag(const char *path, bool verbose = false) const
|
||||
{ return Tag::GetTagEx(tags, path, this, verbose); }
|
||||
|
||||
/// Return the tag at a given path only if it match the required type.
|
||||
Tag *GetTypedTag(const char *path, Variant::Type, bool verbose = false) const;
|
||||
|
||||
bool GetBool(const char *path, bool _default = false, bool verbose = false) const;
|
||||
int GetInteger(const char *path, int _default = -1, bool verbose = false) const;
|
||||
float GetReal(const char *path, float _default = -1.f, bool verbose = false) const;
|
||||
const char *GetString(const char *path, const char *_default = 0, bool verbose = false) const;
|
||||
|
||||
/// Duplicate the structure of a source file into this file.
|
||||
void Import(const File &, bool clear_before_import = true);
|
||||
/// Clone a file and all its tags.
|
||||
File *Clone() const;
|
||||
|
||||
void Free();
|
||||
|
||||
File() : binary_method(Binary_yEnc) {}
|
||||
~File();
|
||||
};
|
||||
|
||||
/*!
|
||||
@short Meta file parser.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct Parser
|
||||
{
|
||||
static const char *ParseTagPreprocessorDirective(Tag &tag, const char *s, const char *e);
|
||||
|
||||
static bool IsMetafile(const char *);
|
||||
|
||||
static bool SaveBinaryTag(IO::Handle &, const Tag &, File::Binary = File::Binary_yEnc);
|
||||
static bool SaveTag(IO::Handle &, const Tag &, File::Binary = File::Binary_yEnc, uint idt = 0);
|
||||
|
||||
static bool ParseTag(Tag &, const char *s, const char *e, const char **r = 0);
|
||||
|
||||
static bool LoadFromMemory(const char *, size_t, File &);
|
||||
static File *Load(const char *, bool verbose = true);
|
||||
static bool Load(const char *, File &, bool verbose = true);
|
||||
|
||||
static bool Save(IO::Handle &, const File &);
|
||||
static bool Save(const char *, const File &);
|
||||
static bool SaveBinary(IO::Handle &, const File &);
|
||||
static bool SaveBinary(const char *, const File &);
|
||||
};
|
||||
|
||||
#define NMLTagForeach(__I__, __T__) ListForeachPtr(GS::NML::Tag *, __I__, (__T__).GetTags())
|
||||
#define NMLFileForeach(__I__, __F__) ListForeachPtr(GS::NML::Tag *, __I__, (__F__).GetTags())
|
||||
|
||||
} // NML
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NMETALANG__
|
||||
60
include/framework/metafile/nml_object.h
Normal file
60
include/framework/metafile/nml_object.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NMETAOBJECT__
|
||||
#define __NMETAOBJECT__
|
||||
|
||||
|
||||
#include "metafile/nml.h"
|
||||
#include "reflection/c_refl.h"
|
||||
|
||||
|
||||
/*!
|
||||
@short Serialization helper.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
namespace GS {
|
||||
namespace NML {
|
||||
|
||||
template <class T> bool LoadFromFile(T &object, File &file)
|
||||
{
|
||||
return file.isEmpty() ? false : object.FromMetaTag(*file.GetTags()[0]);
|
||||
}
|
||||
template <class T> bool LoadFromFile(T &object, const char *path, bool verbose = true)
|
||||
{
|
||||
File file;
|
||||
file.name = path;
|
||||
if (!Parser::Load(path, file, verbose))
|
||||
return false;
|
||||
return LoadFromFile(object, file);
|
||||
}
|
||||
|
||||
template <class T> bool SaveToFile(T &object, File &file)
|
||||
{
|
||||
file.Clear();
|
||||
return file.AddRoot(object.AsMetaTag()) ? true : false;
|
||||
}
|
||||
template <class T> bool SaveToFile(T &object, const char *path)
|
||||
{
|
||||
File file;
|
||||
file.name = path;
|
||||
if (!SaveToFile(object, file))
|
||||
return false;
|
||||
|
||||
return Parser::Save(path, file);
|
||||
}
|
||||
|
||||
bool GenericObjectFromMetaTag(Tag &, void *obj, Reflection::Property *obj_prop);
|
||||
Tag *GenericObjectToMetaTag(Tag *, const void *obj, Reflection::Property *obj_prop);
|
||||
|
||||
bool GenericObjectFromMetaFile(const char *, void *obj, Reflection::Property *obj_prop, const char *root_name = 0);
|
||||
bool GenericObjectToMetaFile(const char *, const void *obj, Reflection::Property *obj_prop, const char *root_name = 0);
|
||||
|
||||
} // NML
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NMETAOBJECT__
|
||||
28
include/framework/metafile/nml_string.h
Normal file
28
include/framework/metafile/nml_string.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NMETAFILE_TO_STRING__
|
||||
#define __NMETAFILE_TO_STRING__
|
||||
|
||||
|
||||
namespace GS {
|
||||
class String;
|
||||
|
||||
namespace NML {
|
||||
class Tag;
|
||||
class File;
|
||||
|
||||
bool TagToString(const Tag &, String &);
|
||||
bool TagFromString(const String &, Tag &);
|
||||
|
||||
bool FileToString(const File &, String &);
|
||||
bool FileFromString(const String &, File &);
|
||||
|
||||
} // NML
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NMETAFILE_TO_STRING__
|
||||
341
include/framework/picture/pict.h
Normal file
341
include/framework/picture/pict.h
Normal file
@ -0,0 +1,341 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NPICTURE__
|
||||
#define __NPICTURE__
|
||||
|
||||
|
||||
#include "geometry/rect.h"
|
||||
#include "picture/pict_color_format.h"
|
||||
#include "memory/bit_field.h"
|
||||
#include "memory/nshared_ptr.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
struct Color;
|
||||
struct Vector4;
|
||||
class Gradient;
|
||||
|
||||
/*!
|
||||
@short The base image class.
|
||||
|
||||
When used with PictureTools, this class provides high-quality sub-pixel
|
||||
bitmap manipulations from shrinking/enlargement to blit/resize.
|
||||
|
||||
Importing/exporting from common image formats can be done through the
|
||||
GS::PictureIO class.
|
||||
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
class Picture : public SharedObject
|
||||
{
|
||||
public:
|
||||
|
||||
NPLACEMENT_NEW(Picture)
|
||||
|
||||
enum BlendMode
|
||||
{
|
||||
BlendReplace = 0,
|
||||
BlendCompose,
|
||||
BlendComposeFast,
|
||||
BlendAdd,
|
||||
BlendMultiply,
|
||||
BlendMultiply2x,
|
||||
BlendAlphaAdd,
|
||||
BlendAlphaMultiply,
|
||||
BlendAlphaMultiply2x,
|
||||
RgbToAlpha
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
uchar *data; ///< Internal pointer to the picture's data.
|
||||
|
||||
uint hash, ///< Raster data hash value.
|
||||
width, ///< Object's width.
|
||||
height; ///< Object's height.
|
||||
|
||||
PixelFormat pxformat; ///< Pixel format.
|
||||
|
||||
/// Zeroify the class but do not free anything.
|
||||
void Zeroify();
|
||||
|
||||
/*!
|
||||
@short Internal free.
|
||||
@note Free raster data only.
|
||||
*/
|
||||
void FreeData();
|
||||
|
||||
enum
|
||||
{
|
||||
PictureIsStub = (1 << 1)
|
||||
};
|
||||
|
||||
BitField protected_flag;
|
||||
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
HasForeignData = (1 << 1)
|
||||
};
|
||||
|
||||
BitField pic_flag;
|
||||
String name;
|
||||
|
||||
/*!
|
||||
@name Blit functions.
|
||||
@{
|
||||
*/
|
||||
/// Blit.
|
||||
static bool Blit(const Picture &src, Picture &dst, const Rect <int> *src_rect = 0, const Rect <int> *dst_rect = 0, BlendMode op = BlendReplace);
|
||||
/// Blit using a mask.
|
||||
static bool BlitMask(const Picture &src, Picture &dst, Picture &mask, const Rect <int> *src_rect = 0, const Rect <int> *dst_rect = 0);
|
||||
/*!
|
||||
@short Scaled blit.
|
||||
|
||||
This function is designed to be used in high quality compositing
|
||||
and perform a bilinear filtered sub-pixel blit.
|
||||
|
||||
@note When a rectangle is omitted the whole picture is used.
|
||||
*/
|
||||
static bool ScaleBlit(Picture &src, Picture &dst, Rect <float> *src_rect = 0, Rect <float> *dst_rect = 0);
|
||||
|
||||
/*!
|
||||
@}
|
||||
@name Cropping/framing functions.
|
||||
@{
|
||||
*/
|
||||
/*!
|
||||
@short Reframe picture.
|
||||
|
||||
All offsets may be negative.
|
||||
Fill color can be specified and defaults to black.
|
||||
|
||||
@note Reframe(-2, -2, 2, 2) to display a 2 pixel-wide frame around
|
||||
the picture.
|
||||
*/
|
||||
bool Reframe(int offset_sx, int offset_sy, int offset_ex, int offset_ey, const Color *fill = 0);
|
||||
/// Crop picture to specified dimension.
|
||||
bool Crop(uint target_width, uint target_height)
|
||||
{ return (target_width <= width) && (target_height <= height) ? Reframe(0, 0, target_width - width, target_height - height) : false; }
|
||||
|
||||
/*!
|
||||
@}
|
||||
@name Rescaling functions.
|
||||
@{
|
||||
*/
|
||||
/*!
|
||||
@short Downscale a picture using area-summing filtering.
|
||||
@note 0 can be used on width or height to resize the picture
|
||||
proportionally.
|
||||
*/
|
||||
bool Downscale(uint width, uint height);
|
||||
/*!
|
||||
@short Resize a picture using bilinear filtering.
|
||||
@note 0 can be used on width or height to resize the picture
|
||||
proportionally.
|
||||
*/
|
||||
bool Resize(uint width, uint height);
|
||||
/// Flip picture.
|
||||
bool Flip(bool flip_h, bool flip_v);
|
||||
|
||||
/*!
|
||||
@}
|
||||
@name Color conversion functions.
|
||||
@{
|
||||
*/
|
||||
protected:
|
||||
|
||||
bool RealToIntegerConversion(const PixelFormat &);
|
||||
bool IntegerToIntegerConversion(const PixelFormat &);
|
||||
bool Fast8888Conversion(const PixelFormat &);
|
||||
|
||||
public:
|
||||
|
||||
bool Swizzle(uchar r = 0, uchar g = 1, uchar b = 2, uchar a = 3);
|
||||
|
||||
/// Convert YUV buffers to RGB buffer.
|
||||
static void YUV422toRGB32(uchar * const yuv_plane[3], uchar *rgb32, int width, int height, int dst_pitch = 0, int dst_height = 0);
|
||||
|
||||
/// Alpha blend two 32bit RGBA values together.
|
||||
static uint ColorBlend(uint u, uint v, float opacity);
|
||||
|
||||
static void AlphaCompositePixel(uchar *data, uchar r, uchar g, uchar b, uchar a);
|
||||
static uchar AlphaCompositeAlpha(uchar a, uchar b);
|
||||
static uchar AlphaCompositeColor(uchar u, uchar v, uchar a, uchar b, uchar k);
|
||||
|
||||
bool ToGrayscale();
|
||||
void Negative(bool r = true, bool g = true, bool b = true, bool a = false);
|
||||
|
||||
void UnpackYCbCr(uchar *y, uchar *cb, uchar *cr);
|
||||
void PackYCbCr(uchar *y, uchar *cb, uchar *cr);
|
||||
|
||||
/*!
|
||||
@}
|
||||
@name Sampling functions.
|
||||
@{
|
||||
*/
|
||||
void Sample(float u, float v, Color &out, uint _w = 0, uint _h = 0) const;
|
||||
void Sample(float u, float v, uint &out, uint _w = 0, uint _h = 0) const;
|
||||
void SampleRGBA(float u, float v, Color &out, uint _w = 0, uint _h = 0) const;
|
||||
|
||||
uint SampleInteger(float u, float v, uint _w = 0, uint _h = 0) const;
|
||||
Color SampleColor(float u, float v, uint _w = 0, uint _h = 0) const;
|
||||
Color SampleRGBAColor(float u, float v, uint _w = 0, uint _h = 0) const;
|
||||
/*!
|
||||
@}
|
||||
@name Drawing functions.
|
||||
@note Most of these functions are for now extremely slow!
|
||||
@{
|
||||
*/
|
||||
protected:
|
||||
|
||||
/// Low-level draw line.
|
||||
void LowLevelDrawLine(bool hq, float sx, float sy, float ex, float ey, float r, float g, float b, float a = 1, const Rect <float> *clip_rect = 0);
|
||||
|
||||
public:
|
||||
|
||||
/// Fill picture with a given color.
|
||||
bool Fill(float r, float g, float b, float a = 1, const Rect <int> *clip_rect = 0, bool lock_alpha = false);
|
||||
|
||||
/// Draw a gradient.
|
||||
void DrawGradient(const Gradient &gradient, const Rect <int> *clip_rect = 0);
|
||||
/*!
|
||||
@short Apply a convolution kernel to the picture.
|
||||
@note Do not use in time critical code as this function is slow
|
||||
and uses a temporary copy of the picture.
|
||||
*/
|
||||
bool ApplyConvolution(uint kernel_width, uint kernel_height, const int *weights, int weight = 256, int pass = 1, const Rect <int> *clip_rect = 0);
|
||||
|
||||
void DrawPlot(float x, float y, float r, float g, float b, float a = 1, const Rect <float> *clip_rect = 0);
|
||||
void DrawPlotHQ(float x, float y, float r, float g, float b, float a = 1, const Rect <float> *clip_rect = 0);
|
||||
|
||||
void DrawLine(float sx, float sy, float ex, float ey, float r, float g, float b, float a = 1, const Rect <float> *clip_rect = 0);
|
||||
void DrawLineHQ(float sx, float sy, float ex, float ey, float r, float g, float b, float a = 1, const Rect <float> *clip_rect = 0);
|
||||
|
||||
void DrawPolygon(uint point_count, Point <float> *point, float r, float g, float b, float a = 1, const Rect <float> *clip_rect = 0);
|
||||
/// @}
|
||||
|
||||
bool ComputeHash();
|
||||
int GetHash() const;
|
||||
|
||||
bool Compare(const Picture &picture) const;
|
||||
|
||||
/// Clone the picture via assignment operator.
|
||||
void operator = (Picture &picture) { Clone(picture); }
|
||||
|
||||
/// Convert the picture to another pixel formats.
|
||||
bool Convert(const PixelFormatDescription &);
|
||||
/// Set the picture format without performing any data conversion.
|
||||
bool SetFormat(const PixelFormatDescription &);
|
||||
|
||||
/*!
|
||||
@short Set the picture dimensions but do not perform any allocation.
|
||||
|
||||
This function is used by the 3d engine built on the picture object.
|
||||
It should not have any practical usage in standard usage.
|
||||
*/
|
||||
void Stub(uint w, uint h);
|
||||
/// Is stub.
|
||||
inline bool IsStub() const { return protected_flag.IsSet(PictureIsStub); }
|
||||
|
||||
/*!
|
||||
@short Return image dimensions as a nfRect.
|
||||
@note sx and sy are 0. Only ex and ey are relevant.
|
||||
*/
|
||||
inline iRect GetRect() const { return iRect(0, 0, width, height); }
|
||||
/*!
|
||||
@short Return image dimensions as a rectangle.
|
||||
@note sx and sy are 0. Only ex and ey are relevant.
|
||||
*/
|
||||
inline void GetRect(iRect &rect) const { rect.Set(0, 0, width, height); }
|
||||
|
||||
/// Test is the picture has an alpha component.
|
||||
bool HasAlpha() const;
|
||||
|
||||
inline uchar *GetData() const { return data; }
|
||||
uchar *GetDataOffset(uint offset_x, uint offset_y) const { return data + (offset_x + offset_y * GetWidth()) * (pxformat.GetBpp() / 8); }
|
||||
|
||||
inline uint GetWidth() const { return width; }
|
||||
inline uint GetHeight() const { return height; }
|
||||
|
||||
inline uchar GetBpp() const { return pxformat.GetBpp(); }
|
||||
inline uint GetPitch() const { return (width * (pxformat.GetBpp() / 8)); }
|
||||
|
||||
inline bool isValid() const { return (width && height && data); }
|
||||
|
||||
/// Return the pixel format descriptor of the picture.
|
||||
inline const PixelFormat &GetPixelFormat() const { return pxformat; }
|
||||
|
||||
void Clone(const Picture &, bool clone_data = true);
|
||||
|
||||
/*
|
||||
@name Memory allocator.
|
||||
@{
|
||||
*/
|
||||
virtual uchar *AllocMemory(size_t);
|
||||
virtual void FreeMemory(uchar *);
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@short Set the picture object raster data source.
|
||||
|
||||
@note Ownership of the data buffer can be passed to this object.
|
||||
*/
|
||||
virtual void SetData(void *data, uint w, uint h, const PixelFormatDescription & = PixelFormat::RGBA8, bool take_ownership = false);
|
||||
/*!
|
||||
@short Allocate internal buffers overriding object settings.
|
||||
|
||||
@note Ownership of the data buffer is passed to this object.
|
||||
@note If the internals already match the new settings this
|
||||
function returns without doing anything unless user data is
|
||||
passed.
|
||||
@note If you provide the picture raster data buffer, you must make
|
||||
sure that the pointer you pass to this function as user_data
|
||||
is at least large enough to hold the complete picture in
|
||||
memory.
|
||||
@see SetData().
|
||||
*/
|
||||
virtual bool AllocAs(uint w, uint h, const PixelFormatDescription & = PixelFormat::RGBA8);
|
||||
/*!
|
||||
@short Free all object's data.
|
||||
|
||||
@note If you used the SetData() function the passed buffer will
|
||||
not be freed by this object. You are responsible for
|
||||
cleaning memory in such case.
|
||||
*/
|
||||
virtual void Free()
|
||||
{
|
||||
FreeData();
|
||||
Zeroify();
|
||||
}
|
||||
|
||||
Picture(const Picture &p)
|
||||
{
|
||||
Zeroify();
|
||||
Clone(p);
|
||||
}
|
||||
Picture(void *data, uint w, uint h, const PixelFormatDescription &f = PixelFormat::RGBA8, bool take_ownership = false)
|
||||
{
|
||||
Zeroify();
|
||||
SetData(data, w, h, f, take_ownership);
|
||||
}
|
||||
Picture(uint w, uint h, const PixelFormatDescription &f = PixelFormat::RGBA8)
|
||||
{
|
||||
Zeroify();
|
||||
AllocAs(w, h, f);
|
||||
}
|
||||
Picture() { Zeroify(); }
|
||||
virtual ~Picture();
|
||||
};
|
||||
|
||||
typedef SharedPtr <Picture> sPicture;
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NPICTURE__
|
||||
147
include/framework/picture/pict_color_format.h
Normal file
147
include/framework/picture/pict_color_format.h
Normal file
@ -0,0 +1,147 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NCOLORFORMAT__
|
||||
#define __NCOLORFORMAT__
|
||||
|
||||
|
||||
#include "nstring/nstring.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/// The color space for a pixel format.
|
||||
enum PixelColorSpace
|
||||
{
|
||||
PixelColorSpace_NULL = 0,
|
||||
PixelColorSpace_RGB ///< Standard RGB space.
|
||||
};
|
||||
|
||||
/// Pixel format descriptor.
|
||||
struct PixelFormatDescription
|
||||
{
|
||||
PixelColorSpace space;
|
||||
/*!
|
||||
When working with integer values these are actual bit masks.
|
||||
However when working with real values they are byte sized offsets
|
||||
in the pixel packet to access a given component.
|
||||
*/
|
||||
uint amask, rmask, gmask, bmask;
|
||||
uchar bpp;
|
||||
bool real;
|
||||
};
|
||||
|
||||
/*!
|
||||
@short Structure holding a picture pixel format.
|
||||
@note This structure only works with continuous bit masks.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
struct PixelFormat
|
||||
{
|
||||
// Predefined pixel formats.
|
||||
static PixelFormatDescription NONE;
|
||||
static PixelFormatDescription BGRA8;
|
||||
static PixelFormatDescription RGBA8;
|
||||
static PixelFormatDescription ARGB8;
|
||||
static PixelFormatDescription BGR8;
|
||||
static PixelFormatDescription RGB8;
|
||||
static PixelFormatDescription RGB555;
|
||||
static PixelFormatDescription RGB565;
|
||||
static PixelFormatDescription RGBA4444;
|
||||
static PixelFormatDescription RGBF;
|
||||
static PixelFormatDescription RGBAF;
|
||||
static PixelFormatDescription YUYV;
|
||||
|
||||
PixelFormatDescription desc;
|
||||
|
||||
uchar ashift, rshift, bshift, gshift;
|
||||
uchar acount, rcount, bcount, gcount;
|
||||
|
||||
/// Get format name (only use for cosmetic purposes! This is not a reliable naming convention).
|
||||
String GetName() const;
|
||||
|
||||
/// Internal function to parse a bit mask.
|
||||
void LoadMask(uint mask, uchar &shift, uchar &count)
|
||||
{
|
||||
shift = Memory::GetShiftCount(mask);
|
||||
count = Memory::GetBitCount(mask);
|
||||
}
|
||||
|
||||
/// Compare a format descriptor to this format.
|
||||
bool operator == (const PixelFormatDescription &fmt) const
|
||||
{
|
||||
if ( (fmt.space != desc.space) || (fmt.bpp != desc.bpp) ||
|
||||
(fmt.amask != desc.amask) || (fmt.rmask != desc.rmask) ||
|
||||
(fmt.gmask != desc.gmask) || (fmt.bmask != desc.bmask) ||
|
||||
(fmt.real != desc.real) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
/// Compare a format descriptor to this format.
|
||||
bool operator != (const PixelFormatDescription &fmt) const
|
||||
{ return !(*this == fmt); }
|
||||
|
||||
/// Return the format bpp.
|
||||
uchar GetBpp() const { return desc.bpp; }
|
||||
|
||||
/// Is format using real or integer numbers.
|
||||
bool IsReal() const { return desc.real; }
|
||||
|
||||
/// Set the the pixel format from user provided data.
|
||||
void Set
|
||||
(
|
||||
PixelColorSpace space = PixelColorSpace_RGB,
|
||||
uint amask = 0xff000000,
|
||||
uint rmask = 0x00ff0000,
|
||||
uint gmask = 0x0000ff00,
|
||||
uint bmask = 0x000000ff,
|
||||
uchar bpp = 32,
|
||||
bool real = false
|
||||
)
|
||||
{
|
||||
desc.amask = amask;
|
||||
desc.rmask = rmask;
|
||||
desc.gmask = gmask;
|
||||
desc.bmask = bmask;
|
||||
desc.bpp = bpp;
|
||||
desc.space = space;
|
||||
LoadMask(amask, ashift, acount);
|
||||
LoadMask(rmask, rshift, rcount);
|
||||
LoadMask(gmask, gshift, gcount);
|
||||
LoadMask(bmask, bshift, bcount);
|
||||
desc.real = real;
|
||||
}
|
||||
/// Set the the pixel format from a descriptor.
|
||||
void Set(const PixelFormatDescription &fmt)
|
||||
{ Set(fmt.space, fmt.amask, fmt.rmask, fmt.gmask, fmt.bmask, fmt.bpp, fmt.real); }
|
||||
|
||||
/// Return a reference to the format descriptor.
|
||||
const PixelFormatDescription &GetDesc() const { return desc; }
|
||||
|
||||
/// Format a color for this color format.
|
||||
uint Format(float r, float g, float b, float a = 1) const;
|
||||
|
||||
/// Constructor.
|
||||
PixelFormat
|
||||
(
|
||||
PixelColorSpace space = PixelColorSpace_RGB,
|
||||
uint amask = 0xff000000,
|
||||
uint rmask = 0x00ff0000,
|
||||
uint gmask = 0x0000ff00,
|
||||
uint bmask = 0x000000ff,
|
||||
uchar bpp = 32,
|
||||
bool real = false
|
||||
)
|
||||
{ Set(space, amask, rmask, gmask, bmask, bpp, real); }
|
||||
/// Constructor via a format descriptor.
|
||||
PixelFormat(const PixelFormatDescription &desc)
|
||||
{ Set(desc); }
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NCOLORFORMAT__
|
||||
51
include/framework/picture/pict_gradient.h
Normal file
51
include/framework/picture/pict_gradient.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NCOLORGRADIENT__
|
||||
#define __NCOLORGRADIENT__
|
||||
|
||||
|
||||
#include "ntypes.h"
|
||||
#include "picture/pict.h"
|
||||
#include "color/color.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*
|
||||
@short Color gradient.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
class Gradient
|
||||
{
|
||||
uint control_point_count;
|
||||
|
||||
Picture::BlendMode op;
|
||||
|
||||
public:
|
||||
|
||||
float k[8]; ///< Gradient coefficient.
|
||||
Color color[8]; ///< Gradient color.
|
||||
|
||||
inline uint GetControlPointCount() const { return control_point_count; }
|
||||
inline Picture::BlendMode GetOperator() const { return op; }
|
||||
|
||||
inline void SetOperator(Picture::BlendMode _op) { op = _op; }
|
||||
inline void Reset() { control_point_count = 0; }
|
||||
|
||||
bool FromMetaTag(NML::Tag *);
|
||||
|
||||
Gradient()
|
||||
{
|
||||
control_point_count = 0;
|
||||
op = Picture::BlendMultiply;
|
||||
}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NCOLORGRADIENT__
|
||||
67
include/framework/picture/pict_io.h
Normal file
67
include/framework/picture/pict_io.h
Normal file
@ -0,0 +1,67 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __NPICTUREIO__
|
||||
#define __NPICTUREIO__
|
||||
|
||||
|
||||
#include "picture/pict_io_codec.h"
|
||||
#include "memory/singleton.h"
|
||||
#include "container/nlist.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*
|
||||
@short Picture I/O class.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
class PictureIO : public Singleton <PictureIO>
|
||||
{
|
||||
AutoList <PictureCodec *> codec_list;
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
@short Generic load function.
|
||||
This function try to load a given resource using all registered
|
||||
codec. This is a convenience function and is not designed to be
|
||||
fast. If you know the file format you are working with then please
|
||||
directly use the appropriate codec.
|
||||
*/
|
||||
bool Load(Picture &, const char *uri);
|
||||
/// Save a picture through a given codec.
|
||||
bool Save(const Picture &, const char *uri, const char *codec_name);
|
||||
|
||||
/// Return a codec from its ID or the file extension it supports.
|
||||
PictureCodec *Codec(const char *codec_name);
|
||||
|
||||
/// Register an I/O codec inside the manager.
|
||||
bool RegisterCodec(PictureCodec *, bool verbose = false);
|
||||
|
||||
/// Delete all registered codec.
|
||||
void DeleteCodecs() { codec_list.Clear(); }
|
||||
|
||||
/// Load a BMP resource via the core codec.
|
||||
bool BmpLoad(Picture &, IO::Handle &);
|
||||
/*!
|
||||
@short Load a TARGA (TGA) resource via the core codec.
|
||||
@note Supported color format are BGRA8/BGR8/RGB24/RGB555
|
||||
both RLE and RAW.
|
||||
*/
|
||||
bool TgaLoad(Picture &, IO::Handle &);
|
||||
/*!
|
||||
@short Save a picture to TARGA (TGA) via the core codec.
|
||||
@note Supported color format are BGRA8/BGR8/RGB24/RGB555.
|
||||
*/
|
||||
bool TgaSave(const Picture &, const char *uri);
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NPICTUREIO__
|
||||
|
||||
51
include/framework/picture/pict_io_codec.h
Normal file
51
include/framework/picture/pict_io_codec.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __NPICTUREIOCODEC__
|
||||
#define __NPICTUREIOCODEC__
|
||||
|
||||
|
||||
#include "filesystem/io_handle.h"
|
||||
#include "nstring/nstring.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
class Picture;
|
||||
|
||||
/*
|
||||
@short Picture I/O codec.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct PictureCodec
|
||||
{
|
||||
enum
|
||||
{
|
||||
NoCaps = 0,
|
||||
|
||||
CanRead = (1 << 0), ///< Codec can read data.
|
||||
CanWrite = (1 << 1), ///< Codec can write data.
|
||||
WriteRaw = (1 << 2), ///< Codec supports raw output.
|
||||
WriteLossy = (1 << 3), ///< Codec supports lossy compression.
|
||||
WriteLossless = (1 << 4), ///< Codec supports lossless compression.
|
||||
AlphaChannel = (1 << 5), ///< Codec supports alpha channel.
|
||||
RealData = (1 << 6) ///< Codec works on real data.
|
||||
};
|
||||
|
||||
virtual bool Load(IO::Handle &, Picture &) = 0;
|
||||
virtual bool Save(IO::Handle &, const Picture &) { return false; }
|
||||
|
||||
virtual const char *GetName() const = 0;
|
||||
virtual const char *GetDesc() const = 0;
|
||||
|
||||
virtual uint GetCaps() const = 0;
|
||||
|
||||
virtual ~PictureCodec() {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NPICTUREIOCODEC__
|
||||
22
include/framework/picture/pict_tools.h
Normal file
22
include/framework/picture/pict_tools.h
Normal file
@ -0,0 +1,22 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __PICT_TOOLS__
|
||||
#define __PICT_TOOLS__
|
||||
|
||||
|
||||
namespace GS {
|
||||
class Picture;
|
||||
namespace PictureTools {
|
||||
|
||||
/// Compare two pictures.
|
||||
bool Compare(const Picture &, const Picture &, float threshold = 0.f);
|
||||
|
||||
} // PictureTools
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __PICT_TOOLS__
|
||||
114
include/framework/plugin/plugin_manager.h
Normal file
114
include/framework/plugin/plugin_manager.h
Normal file
@ -0,0 +1,114 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __PLUGIN_MANAGER__
|
||||
#define __PLUGIN_MANAGER__
|
||||
|
||||
|
||||
#include "shared/shared_library.h"
|
||||
#include "plugin/shared_systems.h"
|
||||
#include "container/nlist.h"
|
||||
#include "nstring/nstring.h"
|
||||
#include "platform.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
static const int PluginLoadOk = 0;
|
||||
static const int PluginLoadError = 1;
|
||||
|
||||
static const int PluginMissingClass = 2;
|
||||
static const int PluginClassError = 3;
|
||||
static const int PluginMissingVersion = 4;
|
||||
static const int PluginVersionError = 5;
|
||||
static const int PluginInterfaceError = 6;
|
||||
|
||||
/*!
|
||||
@short Plugin manager
|
||||
@author Emmanuel Julien (ejulien@owloh.com)
|
||||
*/
|
||||
template <class T> class PluginManager
|
||||
{
|
||||
typedef void SetSharedSystems(SharedSystems &);
|
||||
typedef T *Factory();
|
||||
typedef const char *GetPluginClass();
|
||||
typedef uint GetPluginVersion();
|
||||
|
||||
public:
|
||||
|
||||
struct Plugin
|
||||
{
|
||||
String path;
|
||||
AutoPtr <ISharedLib> shared_lib;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
AutoList <Plugin *> plugins;
|
||||
|
||||
public:
|
||||
|
||||
/// Return a new instance to concrete interface the plugin implements.
|
||||
T *CreatePluginInterface(Plugin *p)
|
||||
{
|
||||
Factory *p_factory = p ? (Factory *)p->shared_lib->GetFunctionPointer("createPluginInterface") : 0;
|
||||
return p_factory ? p_factory() : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@short Load a plugin.
|
||||
|
||||
The plugin is dynamically loaded from the specified path and its
|
||||
class and version are checked for compatibility with the host
|
||||
interface class and version.
|
||||
|
||||
A return code can be passed to get more information on failure.
|
||||
*/
|
||||
Plugin *LoadPlugin(const char *path, int *code = 0)
|
||||
{
|
||||
AutoPtr <Plugin> p(new Plugin);
|
||||
if (p.IsNull())
|
||||
return 0;
|
||||
|
||||
if (code)
|
||||
*code = PluginLoadOk;
|
||||
|
||||
#define Error(V) { if (code) *code = V; return 0; }
|
||||
|
||||
p->shared_lib = Platform::Get().LoadSharedLibrary(path);
|
||||
if (p->shared_lib.IsNull())
|
||||
Error(PluginLoadError);
|
||||
|
||||
GetPluginClass *get_plugin_class = (GetPluginClass *)p->shared_lib->GetFunctionPointer("getPluginClass");
|
||||
GetPluginVersion *get_plugin_version = (GetPluginVersion *)p->shared_lib->GetFunctionPointer("getPluginVersion");
|
||||
SetSharedSystems *set_shared_systems = (SetSharedSystems *)p->shared_lib->GetFunctionPointer("setSharedSystems");
|
||||
|
||||
if (!get_plugin_class)
|
||||
Error(PluginMissingClass);
|
||||
if (!get_plugin_version)
|
||||
Error(PluginMissingVersion);
|
||||
if (!set_shared_systems)
|
||||
Error(PluginInterfaceError);
|
||||
if (String(T::GetPluginClass()) != get_plugin_class())
|
||||
Error(PluginClassError);
|
||||
if (T::GetPluginVersion() != get_plugin_version())
|
||||
Error(PluginVersionError);
|
||||
|
||||
// Set the shared platform pointer.
|
||||
SharedSystems shared;
|
||||
set_shared_systems(shared);
|
||||
|
||||
p->path = path;
|
||||
plugins.Add(p);
|
||||
|
||||
return p.Detach();
|
||||
}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __PLUGIN_MANAGER__
|
||||
37
include/framework/plugin/shared_systems.h
Normal file
37
include/framework/plugin/shared_systems.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __SHARED_SYSTEMS__
|
||||
#define __SHARED_SYSTEMS__
|
||||
|
||||
|
||||
namespace GS {
|
||||
class Platform;
|
||||
class AudioIO;
|
||||
class PictureIO;
|
||||
class LogSystem;
|
||||
|
||||
class SharedSystems
|
||||
{
|
||||
Platform *platform;
|
||||
LogSystem *log_system;
|
||||
PictureIO *picture_io;
|
||||
AudioIO *audio_io;
|
||||
|
||||
public:
|
||||
|
||||
/// Call from the master module responsible for instantiating plugins.
|
||||
void Get();
|
||||
/// Call from a dynamically module to share the master module systems.
|
||||
void Set();
|
||||
|
||||
SharedSystems() : platform(0), log_system(0), picture_io(0), audio_io(0) { Get(); }
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __SHARED_SYSTEMS__
|
||||
31
include/framework/shape/shape.h
Normal file
31
include/framework/shape/shape.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NSHAPE__
|
||||
#define __NSHAPE__
|
||||
|
||||
|
||||
#include "math/vector.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
@short Shape base class.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct Shape
|
||||
{
|
||||
/// Get shape center.
|
||||
virtual Vector4 &GetCenter() const = 0;
|
||||
/// Get distance to support point on a given direction.
|
||||
virtual float GetSupportDistance(const Vector4 &) const = 0;
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NSHAPE__
|
||||
47
include/framework/shape/shape_box.h
Normal file
47
include/framework/shape/shape_box.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
|
||||
nEngine
|
||||
Emmanuel Julien 2000-2010
|
||||
All Rights Reserved
|
||||
|
||||
http://www.gamestart3d.com
|
||||
Please refer to the included license.txt for license informations.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __NSHAPEBOX__
|
||||
#define __NSHAPEBOX__
|
||||
|
||||
|
||||
#include "shape/shape.h"
|
||||
|
||||
|
||||
/*!
|
||||
@short Box shape class.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct nBoxShape : public nShape
|
||||
{
|
||||
Vector4 center;
|
||||
Vector4 half_d;
|
||||
|
||||
virtual Vector4 &GetCenter() const
|
||||
{ return center; }
|
||||
virtual float GetSupportDistance(const Vector4 &d) const
|
||||
{ return d.Abs().Dot(half_d); }
|
||||
|
||||
nSphereShape(const Vector4 &c, const Vector4 &d)
|
||||
{
|
||||
center = c;
|
||||
half_d = d;
|
||||
}
|
||||
nSphereShape()
|
||||
{
|
||||
center.Set(0, 0, 0);
|
||||
half_d.Set(0, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // __NSHAPEBOX__
|
||||
59
include/framework/shape/shape_convex.h
Normal file
59
include/framework/shape/shape_convex.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
|
||||
nEngine
|
||||
Emmanuel Julien 2000-2010
|
||||
All Rights Reserved
|
||||
|
||||
http://www.gamestart3d.com
|
||||
Please refer to the included license.txt for license informations.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __NSHAPECONVEX__
|
||||
#define __NSHAPECONVEX__
|
||||
|
||||
|
||||
#include "shape/shape.h"
|
||||
#include "container/narray.h"
|
||||
|
||||
|
||||
/*!
|
||||
@short Convex shape class.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct nConvexShape : public nShape
|
||||
{
|
||||
Vector4 center;
|
||||
nArray <Vector4> vtx;
|
||||
|
||||
virtual Vector4 &GetCenter() const
|
||||
{ return center; }
|
||||
virtual float GetSupportDistance(const Vector4 &d) const
|
||||
{
|
||||
if (!vtx.GetCount())
|
||||
return 0;
|
||||
|
||||
float d = vtx[0].Dot(d);
|
||||
for (uint n = 1; n < vtx.GetCount(); ++n)
|
||||
{
|
||||
float _d = vtx[n].Dot(d);
|
||||
if (_d > d)
|
||||
d = _d;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
nConvexShape(const Vector4 &c, const nArray <Vector4> &v)
|
||||
{
|
||||
center = c;
|
||||
vtx.Clone(v);
|
||||
}
|
||||
nConvexShape()
|
||||
{
|
||||
center.Set(0, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // __NSHAPECONVEX__
|
||||
47
include/framework/shape/shape_sphere.h
Normal file
47
include/framework/shape/shape_sphere.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
|
||||
nEngine
|
||||
Emmanuel Julien 2000-2010
|
||||
All Rights Reserved
|
||||
|
||||
http://www.gamestart3d.com
|
||||
Please refer to the included license.txt for license informations.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __NSHAPESPHERE__
|
||||
#define __NSHAPESPHERE__
|
||||
|
||||
|
||||
#include "shape/shape.h"
|
||||
|
||||
|
||||
/*!
|
||||
@short Sphere shape class.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct nSphereShape : public nShape
|
||||
{
|
||||
Vector4 center;
|
||||
float radius;
|
||||
|
||||
virtual Vector4 &GetCenter() const
|
||||
{ return center; }
|
||||
virtual float GetSupportDistance(const Vector4 &) const
|
||||
{ return radius; }
|
||||
|
||||
nSphereShape(const Vector4 &c, float r)
|
||||
{
|
||||
center = c;
|
||||
radius = r;
|
||||
}
|
||||
nSphereShape()
|
||||
{
|
||||
center.Set(0, 0, 0);
|
||||
radius = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // __NSHAPESPHERE__
|
||||
111
include/framework/sort/sort.h
Normal file
111
include/framework/sort/sort.h
Normal file
@ -0,0 +1,111 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NSORT__
|
||||
#define __NSORT__
|
||||
|
||||
|
||||
#include "ntypes.h"
|
||||
#include "container/narray.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
Sort class.
|
||||
|
||||
Can sort floating point numbers using QuickSort.
|
||||
Can also sort integer numbers using Radix sort (byte-sort).
|
||||
|
||||
Use T to specify the type of value to sort and O to track a user value in
|
||||
the sorted array (for example an index into the unsorted array).
|
||||
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
template <typename T, typename O> struct Sort
|
||||
{
|
||||
//----------------------------------------------------------------------
|
||||
struct Entry
|
||||
{
|
||||
T v;
|
||||
O o;
|
||||
};
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
protected:
|
||||
|
||||
static void inline SwapEntries(Entry &a, Entry &b)
|
||||
{ Entry t = a; a = b; b = t; }
|
||||
|
||||
static void RecurseQuickSort(Entry *entries, int left, int right)
|
||||
{
|
||||
if (left >= right)
|
||||
return;
|
||||
|
||||
int pivot = (left + right) >> 1;
|
||||
SwapEntries(entries[left], entries[pivot]);
|
||||
|
||||
int ls = left;
|
||||
for (int cr = left + 1; cr <= right; ++cr)
|
||||
if (entries[cr].v < entries[left].v)
|
||||
SwapEntries(entries[cr], entries[++ls]);
|
||||
|
||||
SwapEntries(entries[left], entries[ls]);
|
||||
RecurseQuickSort(entries, left, ls - 1);
|
||||
RecurseQuickSort(entries, ls + 1, right);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// Quicksort n entries in-place.
|
||||
static void QuickSort(int n, Entry *entries)
|
||||
{
|
||||
RecurseQuickSort(entries, 0, n - 1);
|
||||
}
|
||||
|
||||
/// Byte-sort sort n entries from in to out.
|
||||
static Array <Entry> *ByteSort(uint n, Array <Entry> *a, Array <Entry> *b)
|
||||
{
|
||||
if (!a || !b)
|
||||
return 0;
|
||||
|
||||
uint radix[257];
|
||||
|
||||
for (size_t pass = 0; pass < sizeof(T); ++pass)
|
||||
{
|
||||
// clear radix buffer
|
||||
for (uint i = 0; i < 257; ++i)
|
||||
radix[i] = 0;
|
||||
|
||||
// count radix
|
||||
for (uint i = 0; i < n; ++i)
|
||||
++radix[uint((*a)[i].v & 255) + 1];
|
||||
|
||||
// convert count to index
|
||||
for (uint i = 0; i < 256; ++i)
|
||||
radix[i + 1] += radix[i];
|
||||
|
||||
// insert values
|
||||
for (uint i = 0; i < n; i++)
|
||||
{
|
||||
const uint p = radix[uint((*a)[i].v & 255)]++;
|
||||
(*b)[p].v = (*a)[i].v >> 8; // transfer & shift radix
|
||||
(*b)[p].o = (*a)[i].o;
|
||||
}
|
||||
|
||||
// swap arrays
|
||||
Array <Entry> *tmp = b; b = a; a = tmp;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
//----------------------------------------------------------------------
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
51
include/framework/timing/benchmark.h
Normal file
51
include/framework/timing/benchmark.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NBENCHMARK__
|
||||
#define __NBENCHMARK__
|
||||
|
||||
|
||||
#include "time/ntime.h"
|
||||
#include "container/smart_median_average.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
@short Benchmark.
|
||||
@author Emmanuel Julien (ejulien@owloh.com)
|
||||
*/
|
||||
class Benchmark
|
||||
{
|
||||
SmartMedianAverage <float> avg;
|
||||
Time r_clock, t_clock;
|
||||
|
||||
public:
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
float GetMs() const;
|
||||
void Reset();
|
||||
|
||||
Benchmark(bool start = false);
|
||||
};
|
||||
|
||||
/// Scoped benchmark.
|
||||
struct ScopedBenchmark
|
||||
{
|
||||
Benchmark &bench;
|
||||
|
||||
ScopedBenchmark(Benchmark &b) : bench(b)
|
||||
{ bench.Start(); }
|
||||
~ScopedBenchmark()
|
||||
{ bench.Stop(); }
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NBENCHMARK__
|
||||
42
include/framework/timing/loop_benchmark.h
Normal file
42
include/framework/timing/loop_benchmark.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NLOOPBENCHMARK__
|
||||
#define __NLOOPBENCHMARK__
|
||||
|
||||
|
||||
#include "time/ntime.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
@short Loop benchmark tool.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
class LoopBenchmark
|
||||
{
|
||||
uint loop_count;
|
||||
Time r_time, t_time;
|
||||
|
||||
float ms;
|
||||
|
||||
public:
|
||||
|
||||
void MarkLoop();
|
||||
|
||||
float GetMs() const;
|
||||
float GetFps() const;
|
||||
|
||||
void Reset();
|
||||
|
||||
LoopBenchmark() : loop_count(0), ms(0) {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NLOOPBENCHMARK__
|
||||
77
include/framework/timing/profiler.h
Normal file
77
include/framework/timing/profiler.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NPROFILER__
|
||||
#define __NPROFILER__
|
||||
|
||||
|
||||
#include "timing/benchmark.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/*!
|
||||
@short Profiler.
|
||||
@author Emmanuel Julien (ejulien@owloh.com)
|
||||
*/
|
||||
struct Profiler
|
||||
{
|
||||
// System is owned by the profiler.
|
||||
struct System
|
||||
{
|
||||
String label;
|
||||
Benchmark profile;
|
||||
|
||||
AutoList <System *> sub_systems;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
profile.Reset();
|
||||
ListForeachPtr(System *, s, sub_systems)
|
||||
s->Reset();
|
||||
}
|
||||
};
|
||||
|
||||
AutoList <System *> root_systems;
|
||||
|
||||
/*!
|
||||
@short Declare a system.
|
||||
The system can be declared as a sub-system of another system.
|
||||
*/
|
||||
System *DeclareSystem(const char *label, System *subsystem_of = 0)
|
||||
{
|
||||
System *sys = new System;
|
||||
if (sys == 0)
|
||||
return 0;
|
||||
|
||||
sys->label = label;
|
||||
|
||||
if (subsystem_of)
|
||||
subsystem_of->sub_systems.Add(sys);
|
||||
else
|
||||
root_systems.Add(sys);
|
||||
|
||||
return sys;
|
||||
}
|
||||
|
||||
/// Reset all system in the profiler.
|
||||
virtual void ResetProfiles()
|
||||
{
|
||||
ListForeachPtr(System *, s, root_systems)
|
||||
s->Reset();
|
||||
}
|
||||
};
|
||||
|
||||
#if __ENGINE_RETAIL__
|
||||
#define ScopedSystemProfile(_System) ;
|
||||
#else
|
||||
#define ScopedSystemProfile(_System) ScopedBenchmark _scoped_profile(_System->profile);
|
||||
#endif
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NPROFILER__
|
||||
Reference in New Issue
Block a user