summaryrefslogtreecommitdiff
path: root/graphics/asymptote/v3dfile.h
blob: 4bbfdd78876d134c502cfd37c081aa943a87cea2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
 * v3dfile.h
 * Header file for v3d export and types
 *
 * Supakorn "Jamie" Rassameemasmuang <jamievlin@outlook.com> and
 * John C. Bowman
 */

#ifndef V3DFILE_H
#define V3DFILE_H

#include <prc/oPRCFile.h>
#include <zlib.h>

#include "common.h"

#ifdef HAVE_RPC_RPC_H

#include "abs3doutfile.h"
#include "xstream.h"
#include "triple.h"
#include "material.h"
#include "glrender.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;

  [[nodiscard]]
  char const* data() const;

  [[nodiscard]]
  size_t const& length() const;

private:
  xdr::memoxstream memxdrfile;
  string name;
  bool destroyed;
  void close() override;
};

} //namespace camp
#endif

#endif