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