commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
268
include/framework/geometry/curve_nml.cpp
Normal file
268
include/framework/geometry/curve_nml.cpp
Normal file
@ -0,0 +1,268 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "geometry/curve.h"
|
||||
#include "math/nmath.h"
|
||||
#include "sort/sort.h"
|
||||
#include "alloc/ialloc.h"
|
||||
#include "log/log.h"
|
||||
|
||||
using namespace GS;
|
||||
using namespace GS::NML;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Reflection::Enum::Dict Curve::loop_mode_dict[] =
|
||||
{
|
||||
{ Curve::Reset, "Reset" },
|
||||
{ Curve::Constant, "Constant" },
|
||||
{ Curve::Repeat, "Repeat" },
|
||||
{ Curve::Oscillate, "Oscillate" },
|
||||
{ Curve::OffsetAndRepeat, "OffsetAndRepeat" },
|
||||
{ 0, 0 }
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ARM odd address read/write helper functions.
|
||||
void ARM_unaligned_read(float &out, const char *addr)
|
||||
{
|
||||
char *p_out = (char *)&out;
|
||||
for (int n = 0; n < sizeof(float); ++n)
|
||||
p_out[n] = addr[n];
|
||||
}
|
||||
void ARM_unaligned_write(char *addr, const float &in)
|
||||
{
|
||||
const char *p_in = (const char *)∈
|
||||
for (int n = 0; n < sizeof(float); ++n)
|
||||
addr[n] = p_in[n];
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Curve::FromMetaTag(Tag &tag)
|
||||
{
|
||||
if (tag.name != "Curve")
|
||||
__ERR__(__LOG_E__ << "Could not parse curve, incorrect root tag (" << tag.name << ").\n", false)
|
||||
|
||||
Clear();
|
||||
|
||||
// Parse root tags.
|
||||
NMLTagForeach(pt, tag)
|
||||
{
|
||||
if (pt->name == "BinaryKnot")
|
||||
{
|
||||
Tag *count_tag = pt->GetTag("Count"), *data_tag = pt->GetTag("Data");
|
||||
|
||||
if (count_tag && data_tag)
|
||||
{
|
||||
char *data = (char *)data_tag->GetValue().GetBinaryBuffer(), *p_data = data;
|
||||
|
||||
if (data && AllocatePoint(count_tag->GetInteger()))
|
||||
for (uint n = 0; n < points.GetCount(); ++n)
|
||||
{
|
||||
CurvePoint *p = points[n];
|
||||
|
||||
p->shape = CurvePoint::Shape(*p_data++);
|
||||
|
||||
float t;
|
||||
ARM_unaligned_read(t, p_data + 0);
|
||||
p->t.setSec(t);
|
||||
ARM_unaligned_read(p->v, p_data + 4);
|
||||
|
||||
if (p->shape == CurvePoint::Shape_Linear)
|
||||
p_data += 2 * 4;
|
||||
|
||||
else
|
||||
{
|
||||
ARM_unaligned_read(p->tension, p_data + 8);
|
||||
ARM_unaligned_read(p->continuity, p_data + 12);
|
||||
ARM_unaligned_read(p->bias, p_data + 16);
|
||||
|
||||
for (int n = 0; n < 4; ++n)
|
||||
ARM_unaligned_read(p->param[n], p_data + 20 + n * 4);
|
||||
|
||||
p_data += 9 * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pt->name == "Knot")
|
||||
{
|
||||
Tag *st = pt->GetTags()[0];
|
||||
if (!st || (st->name != "Count"))
|
||||
__ERR__(__LOG_E__ << "First sub-tag in <Curve> must be the knot <Count> tag.\n", false)
|
||||
|
||||
if (!AllocatePoint((uint)st->GetInteger()))
|
||||
return false;
|
||||
|
||||
static String _count("Count"), _knot("Knot"), _knotex("KnotEx");
|
||||
|
||||
uint n = 0;
|
||||
NMLTagForeach(st, *pt)
|
||||
{
|
||||
if (st->name == _count)
|
||||
{}
|
||||
|
||||
// Legacy knot definition.
|
||||
if (st->name == _knot)
|
||||
{
|
||||
if (n == points.GetCount())
|
||||
{
|
||||
__LOG_E__ << "Too many knot in <Curve>, " << points.GetCount() << " expected.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if (const char *p = st->GetString())
|
||||
{
|
||||
points[n]->t = Time::fromSec(String::atof(p));
|
||||
points[n]->shape = CurvePoint::Shape_Linear;
|
||||
|
||||
p = String::strfindchar(p, ':');
|
||||
points[n]->v = p[0] ? String::atof(p + 1) : 0;
|
||||
|
||||
n++;
|
||||
}
|
||||
else
|
||||
__LOG_W__ << "Invalid knot tag while parsing curve.\n";
|
||||
}
|
||||
|
||||
/*
|
||||
Extended knot definition.
|
||||
*/
|
||||
else if (st->name == _knotex)
|
||||
{
|
||||
if (n == points.GetCount())
|
||||
{
|
||||
__LOG_E__ << "Too many knot in <Knot>, " << points.GetCount() << " specified.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if (const char *p = st->GetString())
|
||||
{
|
||||
CurvePoint *_knot = points[n];
|
||||
_knot->t = Time::fromSec(String::atof(p));
|
||||
|
||||
// Read shape.
|
||||
p = String::strfindchar(p, ':');
|
||||
int shape = p[0] ? String::atoi(p + 1) : 0;
|
||||
p++;
|
||||
|
||||
switch (shape)
|
||||
{
|
||||
default:
|
||||
case 0: _knot->shape = CurvePoint::Shape_None; break;
|
||||
case 1: _knot->shape = CurvePoint::Shape_Linear; break;
|
||||
case 2: _knot->shape = CurvePoint::Shape_Bezier; break;
|
||||
case 3: _knot->shape = CurvePoint::Shape_Bezier2; break;
|
||||
case 4: _knot->shape = CurvePoint::Shape_Hermite; break;
|
||||
case 5: _knot->shape = CurvePoint::Shape_TCB; break;
|
||||
case 6: _knot->shape = CurvePoint::Shape_Step; break;
|
||||
}
|
||||
|
||||
// Read knot parameters.
|
||||
//--------------------------------------------
|
||||
#define GetInputKnotParamEx(_PARM_)\
|
||||
{\
|
||||
p = String::strfindchar(p, ':');\
|
||||
(_PARM_) = p[0] ? String::atof(p + 1) : -1;\
|
||||
p++;\
|
||||
}
|
||||
//--------------------------------------------
|
||||
|
||||
GetInputKnotParamEx(_knot->v);
|
||||
GetInputKnotParamEx(_knot->tension);
|
||||
GetInputKnotParamEx(_knot->continuity);
|
||||
GetInputKnotParamEx(_knot->bias);
|
||||
|
||||
GetInputKnotParamEx(_knot->param[0]);
|
||||
GetInputKnotParamEx(_knot->param[1]);
|
||||
GetInputKnotParamEx(_knot->param[2]);
|
||||
GetInputKnotParamEx(_knot->param[3]);
|
||||
n++;
|
||||
}
|
||||
else
|
||||
__LOG_W__ << "Invalid extended knot tag while parsing curve.\n";
|
||||
}
|
||||
else
|
||||
__LOG_W__ << "Unsupported knot tag '" << st->name << "'.\n";
|
||||
}
|
||||
|
||||
// Incomplete/erroneous definition.
|
||||
if (n != points.GetCount())
|
||||
{
|
||||
Clear();
|
||||
__ERR__(__LOG_E__ << "<Curve> is corrupted, discarding.\n", false)
|
||||
}
|
||||
}
|
||||
else __LOG_W__ << "Unknown tag '" << pt->name << "' in <Curve>.\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Tag *Curve::AsMetaTag() const
|
||||
{
|
||||
Tag *root = new Tag("Curve");
|
||||
if (!root)
|
||||
__ERR__(__LOG_E__ << "Could not create curve root tag to serialize.\n", NULL)
|
||||
|
||||
// Binary knots.
|
||||
if (points.GetCount())
|
||||
if (Tag *binary_knot_tag = root->AddChild("BinaryKnot"))
|
||||
{
|
||||
binary_knot_tag->AddChild("Count", points.GetCount());
|
||||
|
||||
// Get size.
|
||||
int size = 0;
|
||||
for (uint n = 0; n < points.GetCount(); ++n)
|
||||
{
|
||||
CurvePoint *_knot = points[n];
|
||||
|
||||
// Legacy definition.
|
||||
if (_knot->shape == CurvePoint::Shape_Linear)
|
||||
size += 2 * 4; // Knot size.
|
||||
else size += 9 * 4; // Extended knot size.
|
||||
}
|
||||
|
||||
// Output binary.
|
||||
Array <char> knot_array(points.GetCount() + size);
|
||||
char *p_knot = knot_array;
|
||||
|
||||
for (uint n = 0; n < points.GetCount(); ++n)
|
||||
{
|
||||
CurvePoint *_knot = points[n];
|
||||
|
||||
*p_knot++ = uchar(_knot->shape);
|
||||
|
||||
float t = _knot->t.toSec();
|
||||
ARM_unaligned_write(p_knot + 0, t);
|
||||
ARM_unaligned_write(p_knot + 4, _knot->v);
|
||||
|
||||
if (_knot->shape == CurvePoint::Shape_Linear)
|
||||
p_knot += 2 * 4;
|
||||
|
||||
else
|
||||
{
|
||||
ARM_unaligned_write(p_knot + 8, _knot->tension);
|
||||
ARM_unaligned_write(p_knot + 12, _knot->continuity);
|
||||
ARM_unaligned_write(p_knot + 16, _knot->bias);
|
||||
|
||||
for (int n = 0; n < 4; ++n)
|
||||
ARM_unaligned_write(p_knot + 20 + n * 4, _knot->param[n]);
|
||||
|
||||
p_knot += 9 * 4;
|
||||
}
|
||||
}
|
||||
|
||||
binary_knot_tag->AddChild("Data", knot_array, points.GetCount() + size);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user