charles/src/yaml/objectParser.cc

289 lines
6.7 KiB
C++
Raw Normal View History

2014-07-17 20:14:52 -07:00
/* object_parser.cc
* vim: set tw=80:
* Eryn Wells <eryn@erynwells.me>
*/
/**
* Implementation of ObjectParser.
*/
#include <cassert>
#include <string>
#include <vector>
2014-08-09 21:23:11 -07:00
#include "material.hh"
#include "object.hh"
#include "objectBox.hh"
#include "objectPlane.hh"
#include "objectSphere.hh"
2014-07-19 14:45:37 -07:00
#include "yaml/objectParser.hh"
#include "yaml/vectorParser.hh"
2014-07-17 20:14:52 -07:00
2014-08-09 21:23:11 -07:00
using charles::basics::Color;
using charles::basics::Vector4;
namespace charles {
2014-07-17 20:14:52 -07:00
namespace yaml {
ObjectParser::ObjectParser(Scene& scene,
ParserStack& parsers,
const std::string& tag)
2014-07-19 14:45:37 -07:00
: ScalarMappingParser(scene, parsers),
mObject(nullptr),
2014-07-19 14:45:37 -07:00
mSection(NoSection)
{
if (tag == "!Object.Box") {
mType = Type::Box;
mObject.reset(new Box());
} else if (tag == "!Object.Plane") {
mType = Type::Plane;
mObject.reset(new Plane());
} else if (tag == "!Object.Sphere") {
mType = Type::Sphere;
mObject.reset(new Sphere());
} else {
assert(false);
}
2014-08-09 21:23:11 -07:00
GetScene().AddObject(mObject);
}
2014-07-17 20:14:52 -07:00
2014-07-19 14:45:37 -07:00
ObjectParser::~ObjectParser()
{
mObject.reset();
}
2014-07-19 14:45:37 -07:00
void
ObjectParser::HandleKeyEvent(const std::string& key)
{
static const std::map<std::string, Section> sCommonSections = {
{"color", ColorSection}
};
static const std::map<std::string, Section> sSphereSections = {
2014-07-19 14:45:37 -07:00
{"origin", OriginSection},
2014-07-19 15:42:31 -07:00
{"radius", RadiusSection}
2014-07-19 14:45:37 -07:00
};
static const std::map<std::string, Section> sBoxSections = {
{"near", NearSection},
{"far", FarSection}
};
static const std::map<std::string, Section> sPlaneSections = {
{"normal", NormalSection},
{"distance", DistanceSection}
};
if (sCommonSections.count(key) > 0) {
mSection = sCommonSections.at(key);
return;
2014-07-19 14:45:37 -07:00
}
if (mType == Type::Box) {
if (sBoxSections.count(key) > 0) {
mSection = sBoxSections.at(key);
} else {
mSection = NoSection;
}
} else if (mType == Type::Plane) {
if (sPlaneSections.count(key) > 0) {
mSection = sPlaneSections.at(key);
} else {
mSection = NoSection;
}
} else if (mType == Type::Sphere) {
if (sSphereSections.count(key) > 0) {
mSection = sSphereSections.at(key);
} else {
mSection = NoSection;
}
} else {
assert(false);
2014-07-19 14:45:37 -07:00
}
}
2014-07-17 20:14:52 -07:00
void
2014-07-19 14:45:37 -07:00
ObjectParser::HandleValueEvent(yaml_event_t& event)
2014-07-17 20:14:52 -07:00
{
switch (mSection) {
2014-07-19 14:45:37 -07:00
case ColorSection:
HandleColorEvent(event);
2014-07-17 20:14:52 -07:00
break;
/* Spheres */
2014-07-17 20:14:52 -07:00
case OriginSection:
2014-07-19 14:45:37 -07:00
HandleOriginEvent(event);
2014-07-17 20:14:52 -07:00
break;
case RadiusSection:
2014-07-19 14:45:37 -07:00
HandleRadiusEvent(event);
2014-07-17 20:14:52 -07:00
break;
/* Boxes */
case NearSection:
HandleNearEvent(event);
break;
case FarSection:
HandleFarEvent(event);
break;
/* Planes */
case NormalSection:
HandleNormalEvent(event);
break;
case DistanceSection:
HandleDistanceEvent(event);
break;
2014-07-17 20:14:52 -07:00
default:
assert(false);
break;
}
}
void
2014-07-19 14:45:37 -07:00
ObjectParser::HandleColorEvent(yaml_event_t& event)
2014-07-17 20:14:52 -07:00
{
2014-07-19 14:45:37 -07:00
if (event.type != YAML_SEQUENCE_START_EVENT) {
/* TODO: Clean this up. */
2014-07-19 14:45:37 -07:00
assert(event.type != YAML_SEQUENCE_START_EVENT);
2014-07-17 20:14:52 -07:00
return;
}
auto onDone = [this](Color color) {
mObject->GetMaterial().SetDiffuseColor(color);
2014-07-19 14:45:37 -07:00
mSection = NoSection;
SetShouldExpectKey(true);
};
GetParsers().push(new ColorParser(GetScene(), GetParsers(), onDone));
2014-07-17 20:14:52 -07:00
}
void
ObjectParser::HandleOriginEvent(yaml_event_t& event)
{
if (event.type != YAML_SEQUENCE_START_EVENT) {
/* TODO: Clean this up. */
assert(event.type != YAML_SEQUENCE_START_EVENT);
return;
2014-07-17 20:14:52 -07:00
}
2014-08-09 21:23:11 -07:00
auto onDone = [this](Vector4 origin) {
/* TODO: Once Place() and Move() are implemented on Object, use that. */
#if 0
mObject->SetOrigin(origin);
2014-07-17 20:14:52 -07:00
mSection = NoSection;
2014-07-19 14:45:37 -07:00
SetShouldExpectKey(true);
2014-08-09 21:23:11 -07:00
#endif
2014-07-17 20:14:52 -07:00
};
2014-07-19 14:45:37 -07:00
2014-08-09 21:23:11 -07:00
GetParsers().push(new Vector4Parser(GetScene(), GetParsers(), onDone));
2014-07-17 20:14:52 -07:00
}
void
ObjectParser::HandleRadiusEvent(yaml_event_t& event)
{
if (event.type != YAML_SCALAR_EVENT) {
/* TODO: Clean this up. */
assert(false);
}
double radius;
std::string scalar((char *)event.data.scalar.value,
event.data.scalar.length);
if (!ParseScalar<double>(scalar, radius)) {
2014-07-17 20:14:52 -07:00
/* TODO: Clean this up. */
assert(false);
}
std::dynamic_pointer_cast<Sphere>(mObject)->SetRadius(radius);
2014-07-17 20:14:52 -07:00
mSection = NoSection;
SetShouldExpectKey(true);
2014-07-17 20:14:52 -07:00
}
void
ObjectParser::HandleNearEvent(yaml_event_t& event)
{
if (event.type != YAML_SEQUENCE_START_EVENT) {
/* TODO: Clean this up. */
assert(event.type != YAML_SEQUENCE_START_EVENT);
return;
}
2014-08-09 21:23:11 -07:00
auto onDone = [this](Vector4 near) {
std::dynamic_pointer_cast<Box>(mObject)->SetNear(near);
mSection = NoSection;
SetShouldExpectKey(true);
};
2014-08-09 21:23:11 -07:00
GetParsers().push(new Vector4Parser(GetScene(), GetParsers(), onDone));
}
void
ObjectParser::HandleFarEvent(yaml_event_t& event)
{
if (event.type != YAML_SEQUENCE_START_EVENT) {
/* TODO: Clean this up. */
assert(event.type != YAML_SEQUENCE_START_EVENT);
return;
}
2014-08-09 21:23:11 -07:00
auto onDone = [this](Vector4 far) {
std::dynamic_pointer_cast<Box>(mObject)->SetFar(far);
mSection = NoSection;
SetShouldExpectKey(true);
};
2014-08-09 21:23:11 -07:00
GetParsers().push(new Vector4Parser(GetScene(), GetParsers(), onDone));
}
void
ObjectParser::HandleNormalEvent(yaml_event_t& event)
{
if (event.type != YAML_SEQUENCE_START_EVENT) {
/* TODO: Clean this up. */
assert(event.type != YAML_SEQUENCE_START_EVENT);
return;
}
2014-08-09 21:23:11 -07:00
auto onDone = [this](Vector4 normal) {
std::dynamic_pointer_cast<Plane>(mObject)->SetNormal(normal);
mSection = NoSection;
SetShouldExpectKey(true);
};
2014-08-09 21:23:11 -07:00
GetParsers().push(new Vector4Parser(GetScene(), GetParsers(), onDone));
}
void
ObjectParser::HandleDistanceEvent(yaml_event_t& event)
{
if (event.type != YAML_SCALAR_EVENT) {
/* TODO: Clean this up. */
assert(false);
}
Double distance;
std::string scalar((char *)event.data.scalar.value,
event.data.scalar.length);
if (!ParseScalar<Double>(scalar, distance)) {
/* TODO: Clean this up. */
assert(false);
}
std::dynamic_pointer_cast<Plane>(mObject)->SetDistance(distance);
mSection = NoSection;
SetShouldExpectKey(true);
}
2014-07-17 20:14:52 -07:00
} /* namespace yaml */
} /* namespace charles */