1 #include "xr_mesh_vbuf.h"
2
3 using namespace xray_re;
4
extend(T * & source,size_t new_size)5 template<typename T> void xr_mesh_vbuf::extend(T*& source, size_t new_size)
6 {
7 T* target = new T[new_size];
8 if (source)
9 copy(source, target, size());
10 delete source;
11 source = target;
12 }
13
transform_normals(const fvector3 * source,fvector3 * target,size_t size,const fmatrix & xform) const14 void xr_mesh_vbuf::transform_normals(const fvector3* source, fvector3* target, size_t size,
15 const fmatrix& xform) const
16 {
17 dmatrix m;
18 m.set(xform);
19 m.i.normalize();
20 m.j.normalize();
21 m.k.normalize();
22 for (; size != 0; --size, ++target)
23 target->set(dvector3().set(*source++).rotate(m));
24 }
25
transform_points(const fvector3 * source,fvector3 * target,size_t size,const fmatrix & xform) const26 void xr_mesh_vbuf::transform_points(const fvector3* source, fvector3* target, size_t size,
27 const fmatrix& xform) const
28 {
29 dmatrix m;
30 m.set(xform);
31 for (; size != 0; --size, ++target)
32 target->set(dvector3().set(*source++).transform(m));
33 }
34
clear()35 void xr_mesh_vbuf::clear()
36 {
37 xr_vbuf::clear();
38 m_reserved = 0;
39 }
40
set_signature(uint32_t _signature)41 void xr_mesh_vbuf::set_signature(uint32_t _signature)
42 {
43 xr_assert(size() == 0);
44 m_signature = _signature;
45 }
46
reserve(size_t reserved)47 void xr_mesh_vbuf::reserve(size_t reserved)
48 {
49 if (reserved <= size())
50 return;
51 if (has_points())
52 extend(m_points, reserved);
53 if (has_normals())
54 extend(m_normals, reserved);
55 if (has_texcoords())
56 extend(m_texcoords, reserved);
57 if (has_influences())
58 extend(m_influences, reserved);
59 if (has_colors())
60 extend(m_colors, reserved);
61 m_reserved = reserved;
62 }
63
push(const xr_vbuf & vb,const xr_ibuf * ib,const fmatrix * xform)64 void xr_mesh_vbuf::push(const xr_vbuf& vb, const xr_ibuf* ib, const fmatrix* xform)
65 {
66 if (signature() == 0) {
67 xr_assert(size() == 0);
68 set_signature(vb.signature());
69 }
70 size_t new_size = size() + vb.size();
71 if (m_reserved < new_size)
72 reserve(new_size);
73 if (has_points()) {
74 xr_assert(vb.has_points());
75 if (xform)
76 transform_points(vb.p(), m_points + size(), vb.size(), *xform);
77 else
78 copy(vb.p(), m_points + size(), vb.size());
79 }
80 if (has_normals()) {
81 if (vb.has_normals()) {
82 if (false && xform)
83 transform_normals(vb.n(), m_normals + size(), vb.size(), *xform);
84 else
85 copy(vb.n(), m_normals + size(), vb.size());
86 } else {
87 // generate fake normals for 1xxx builds.
88 // FIXME (maybe): this will not work correctly for the duplicate faces.
89 xr_assert(ib);
90 fvector3* normals = m_normals + size();
91 for (size_t i = 0, num_indices = ib->size(); i < num_indices; i += 3) {
92 uint32_t v0 = (*ib)[i + 0];
93 uint32_t v1 = (*ib)[i + 1];
94 uint32_t v2 = (*ib)[i + 2];
95 fvector3 normal;
96 normal.calc_normal(vb.p(v0), vb.p(v1), vb.p(v2));
97 normals[v0].set(normal);
98 normals[v1].set(normal);
99 normals[v2].set(normal);
100 }
101 }
102 }
103 if (has_texcoords()) {
104 xr_assert(vb.has_texcoords());
105 copy(vb.tc(), m_texcoords + size(), vb.size());
106 if (m_tc_fix) {
107 fvector2* uv = m_texcoords + size();
108 for (size_t n = vb.size(); n != 0; --n, ++uv)
109 uv->mul(0.5f);
110 }
111 }
112 // intentionally ignoring lightmaps here
113 if (has_influences()) {
114 xr_assert(vb.has_influences());
115 copy(vb.w(), m_influences + size(), vb.size());
116 }
117 if (has_colors()) {
118 xr_assert(vb.has_colors());
119 copy(vb.c(), m_colors + size(), vb.size());
120 }
121 set_size(new_size);
122 }
123