/*
* v3dfile.h
* Header file for v3d export and types
*
* Supakorn "Jamie" Rassameemasmuang <
[email protected]> and
* John C. Bowman
*/
#ifndef V3DFILE_H
#define V3DFILE_H
#include <prc/oPRCFile.h>
#include <zlib.h>
#include "common.h"
#ifdef HAVE_LIBTIRPC
#include "abs3doutfile.h"
#include "xstream.h"
#include "triple.h"
#include "material.h"
#define transform transform_
#include "v3dtypes.h"
#undef transform
#include "v3dheadertypes.h"
namespace camp
{
class AHeader
{
public:
v3dheadertypes ty;
AHeader(v3dheadertypes const& ty) : ty(ty) {}
virtual ~AHeader() = default;
virtual uint32_t getWordSize(bool singleprecision) const = 0;
virtual void writeContent(xdr::oxstream& ox) const = 0;
};
template<typename T, uint32_t realWords, uint32_t floatWords=0>
class SingleObjectHeader : public AHeader
{
public:
SingleObjectHeader(v3dheadertypes const& ty, T const& ob) : AHeader(ty), obj(ob)
{
}
~SingleObjectHeader() override = default;
protected:
uint32_t getWordSize(bool singleprecision) const override
{
return (singleprecision ? 1 : 2)*realWords+floatWords;
}
void writeContent(xdr::oxstream &ox) const override
{
ox << obj;
}
private:
T obj;
};
using open_mode=xdr::xios::open_mode;
using TripleHeader=SingleObjectHeader<triple,3>;
using PairHeader=SingleObjectHeader<pair,2>;
using DoubleHeader=SingleObjectHeader<double,1>;
using Uint32Header=SingleObjectHeader<uint32_t,0,1>;
using RGBAHeader=SingleObjectHeader<prc::RGBAColour,0,4>;
const unsigned int v3dVersion=1;
class LightHeader : public AHeader
{
public:
LightHeader(triple const& direction, prc::RGBAColour const& color);
~LightHeader() override=default;
protected:
[[nodiscard]]
uint32_t getWordSize(bool singleprecision) const override;
void writeContent(xdr::oxstream &ox) const override;
private:
triple direction;
prc::RGBAColour color;
};
class v3dfile : public abs3Doutfile {
private:
bool finalized;
public:
v3dfile(bool singleprecision=false) : abs3Doutfile(singleprecision),
finalized(false) {}
void writeInit();
void finalize();
void addPatch(triple const* controls, prc::RGBAColour const* c) override;
void addStraightPatch(
triple const* controls, prc::RGBAColour const* c) override;
void addBezierTriangle(
triple const* control, prc::RGBAColour const* c) override;
void addStraightBezierTriangle(
triple const* controls, prc::RGBAColour const* c) override;
#ifdef HAVE_LIBGLM
void addMaterial(Material const& mat) override;
#endif
void addSphere(triple const& center, double radius) override;
void addHemisphere(triple const& center, double radius, double const& polar, double const& azimuth) override;
void addCylinder(triple const& center, double radius, double height,
double const& polar, const double& azimuth,
bool core) override;
void addDisk(triple const& center, double radius,
double const& polar, const double& azimuth) override;
void addTube(const triple *g, double width, bool core) override;
void addTriangles(size_t nP, const triple* P, size_t nN,
const triple* N, size_t nC, const prc::RGBAColour* C,
size_t nI, const uint32_t (*PI)[3],
const uint32_t (*NI)[3],
const uint32_t (*CI)[3]) override;
void addCurve(triple const& z0, triple const& c0, triple const& c1,
triple const& z1) override;
void addCurve(triple const& z0, triple const& z1) override;
void addPixel(triple const& z0, double width) override;
void precision(int digits) override {}
protected:
#ifdef HAVE_LIBGLM
void addvec4(glm::vec4 const& vec);
#endif
void addCenterIndexMat();
void addIndices(uint32_t const* trip);
void addTriples(triple const* triples, size_t n);
void addColors(prc::RGBAColour const* col, size_t nc);
void addHeaders();
void addCenters();
virtual xdr::oxstream& getXDRFile() = 0;
};
class gzv3dfile : public v3dfile {
public:
gzv3dfile(string const& name, bool singleprecision=false);
~gzv3dfile() override;
protected:
xdr::oxstream& getXDRFile() override;
private:
xdr::memoxstream memxdrfile;
string name;
bool destroyed;
void close() override;
};
} //namespace camp
#endif
#endif